<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4982860166412548129</id><updated>2011-12-16T12:59:28.490+02:00</updated><category term='ubiquitous computing'/><category term='Double'/><category term='context model'/><category term='Cyprus'/><category term='Location'/><category term='Binding'/><category term='Byte Array'/><category term='development'/><category term='gestures'/><category term='UI'/><category term='Tutorial'/><category term='Windows'/><category term='ontology'/><category term='phd research'/><category term='Apple'/><category term='IDE'/><category term='Conversion'/><category term='travel'/><category term='Audio'/><category term='CSI'/><category term='mobile platforms'/><category term='family'/><category term='Context-aware Media Player'/><category term='diamond head'/><category term='iPod touch'/><category term='Humor'/><category term='semantics'/><category term='Float'/><category term='Components'/><category term='touch-screen'/><category term='Services'/><category term='Video'/><category term='context clients'/><category term='GMail'/><category term='isd2008'/><category term='TV'/><category term='context-aware'/><category term='IDEA'/><category term='OSGi'/><category term='adaptive software'/><category term='research'/><category term='cloud computing'/><category term='vacation'/><category term='Declarative services'/><category term='JetBrains'/><category term='Hawaii'/><category term='MUSIC-IST'/><category term='oahu'/><category term='Java'/><category term='Boolean'/><category term='Short'/><category term='Google'/><category term='hanauma'/><category term='Development methodology'/><category term='Maps'/><category term='android'/><category term='IntelliJ'/><category term='iTunes'/><category term='data structures'/><category term='Long'/><category term='software'/><category term='mobile computing'/><category term='kailua'/><category term='GPS'/><category term='Geosensing'/><category term='Int'/><category term='Command-Line Interface (CLI)'/><category term='Pros and Cons'/><category term='context plug-ins'/><category term='middleware'/><category term='CaMP'/><category term='Online tools'/><category term='Utilities'/><title type='text'>Nearchos Paspallis: My Blog</title><subtitle type='html'>Writing about technology, traveling, politics and more</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-4674268386481272706</id><published>2010-12-07T18:07:00.003+02:00</published><updated>2010-12-09T10:50:45.668+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Short'/><category scheme='http://www.blogger.com/atom/ns#' term='Double'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Byte Array'/><category scheme='http://www.blogger.com/atom/ns#' term='Utilities'/><category scheme='http://www.blogger.com/atom/ns#' term='Conversion'/><category scheme='http://www.blogger.com/atom/ns#' term='Boolean'/><category scheme='http://www.blogger.com/atom/ns#' term='Float'/><category scheme='http://www.blogger.com/atom/ns#' term='Long'/><category scheme='http://www.blogger.com/atom/ns#' term='Int'/><title type='text'>Conversion utilities in Java</title><content type='html'>Since the beginning of 2010, I have been involved in &lt;a href="http://www.asterics.eu/"&gt;AsTeRICS&lt;/a&gt;. This is an EU-funded project aiming to provide a software construction toolset for allowing prototyping of Assistive Technology (AT) applications. These applications should be adapted to the motor abilities of&amp;nbsp;end-users.&lt;br /&gt;&lt;br /&gt;My involvement in the project varies as a result of my main workload, which this semester includes teaching an &lt;a href="http://www.cs.ucy.ac.cy/~paspalli/courses/fall2010/epl001"&gt;introductory computer science course&lt;/a&gt;, and a &lt;a href="http://www.cs.ucy.ac.cy/~paspalli/courses/fall2010/epl603"&gt;postgraduate course in software engineering&lt;/a&gt;. Lately, a request was placed for a clear way for converting a primitive type (or string) in Java to a byte array, and back. This is required to enable a custom protocol that will allow the configuration and test module to connect remotely to the AsTeRICS middleware.&lt;br /&gt;&lt;br /&gt;I had done something similar before, but only for integer primitive data types. After searching the web for an answer, I realized that there are some methods available but none is clear enough. I quickly realized that this functionality is "almost" built-in Java via the &lt;a href="http://download.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html"&gt;java.nio.ByteBuffer&lt;/a&gt; class. This class allows for converting primitive types such as short, int, and long to byte arrays. Scalar data types such as&amp;nbsp;float and double can also be converted to byte arrays through an intermediate conversion to int and long respectively.&lt;br /&gt;&lt;br /&gt;The resulting code is posted here, and is available for download as a Java class named &lt;a href="http://member.acm.org/~nearchos/ConversionUtils.java"&gt;ConversionUtils&lt;/a&gt;.&lt;br /&gt;&lt;pre style="background: #ccc;"&gt;import java.nio.ByteBuffer;&lt;br /&gt;&lt;br /&gt;public class ConversionUtils&lt;br /&gt;{&lt;br /&gt;    public static final byte FALSE_BITS = 0x00;&lt;br /&gt;    public static final byte TRUE_BITS = 0x01;&lt;br /&gt;&lt;br /&gt;    static public boolean booleanFromByte(final byte bits)&lt;br /&gt;    {&lt;br /&gt;        return bits != FALSE_BITS;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte booleanToByte(final boolean b)&lt;br /&gt;    {&lt;br /&gt;        return b ? TRUE_BITS : FALSE_BITS;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public short shortFromBytes(final byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;        return ByteBuffer.wrap(bytes).getShort();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] shortToBytes(final short s)&lt;br /&gt;    {&lt;br /&gt;        return new byte [] {&lt;br /&gt;                (byte)(s &amp;gt;&amp;gt;&amp;gt; 8),&lt;br /&gt;                (byte) s};&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public int intFromBytes(final byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;        return ByteBuffer.wrap(bytes).getInt();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] intToBytes(final int i)&lt;br /&gt;    {&lt;br /&gt;        return new byte [] {&lt;br /&gt;                (byte)(i &amp;gt;&amp;gt;&amp;gt; 24),&lt;br /&gt;                (byte)(i &amp;gt;&amp;gt;&amp;gt; 16),&lt;br /&gt;                (byte)(i &amp;gt;&amp;gt;&amp;gt; 8),&lt;br /&gt;                (byte) i};&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public long longFromBytes(final byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;        return ByteBuffer.wrap(bytes).getLong();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] longToBytes(final long l)&lt;br /&gt;    {&lt;br /&gt;        return new byte [] {&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 56),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 48),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 40),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 32),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 24),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 16),&lt;br /&gt;                (byte)(l &amp;gt;&amp;gt;&amp;gt; 8),&lt;br /&gt;                (byte) l};&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public float floatFromBytes(byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;        final int bits = intFromBytes(bytes);&lt;br /&gt;        return Float.intBitsToFloat(bits);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] floatToBytes(final float f)&lt;br /&gt;    {&lt;br /&gt;        int i = Float.floatToRawIntBits(f);&lt;br /&gt;        return intToBytes(i);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] doubleToBytes(final double d)&lt;br /&gt;    {&lt;br /&gt;        long l = Double.doubleToRawLongBits(d);&lt;br /&gt;        return longToBytes(l);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public double doubleFromBytes(byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;        final long bits = longFromBytes(bytes);&lt;br /&gt;        return Double.longBitsToDouble(bits);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public byte [] stringToBytes(final String s)&lt;br /&gt;    {&lt;br /&gt;        return s.getBytes();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static public String stringFromBytes(byte [] bytes)&lt;br /&gt;    {&lt;br /&gt;  return new String(bytes);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above code can be tested using the following:&lt;br /&gt;&lt;pre style="background: #ccc;"&gt;import java.nio.ByteBuffer;&lt;br /&gt;&lt;br /&gt;public static String toString(final byte [] bits)&lt;br /&gt;    {&lt;br /&gt;        final StringBuffer stringBuffer = new StringBuffer(bits.length * 8);&lt;br /&gt;        for(final byte b : bits)&lt;br /&gt;        {&lt;br /&gt;            stringBuffer.append(toString(b));&lt;br /&gt;        }&lt;br /&gt;        return stringBuffer.toString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static String toString(final byte bits)&lt;br /&gt;    {&lt;br /&gt;        final int displayMask = 1 &amp;lt;&amp;lt; 7;&lt;br /&gt;        final StringBuffer buf = new StringBuffer(8);&lt;br /&gt;&lt;br /&gt;        byte value = bits;&lt;br /&gt;        for(int c = 1; c &amp;lt;= 8; c++)&lt;br /&gt;        {&lt;br /&gt;            buf.append((value &amp;amp; displayMask) == 0 ? '0' : '1' );&lt;br /&gt;            value &amp;lt;&amp;lt;= 1;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return buf.toString();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args)&lt;br /&gt;    {&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final boolean b_f = false;&lt;br /&gt;            System.out.println("boolean false: " + b_f);&lt;br /&gt;            final byte bits = booleanToByte(b_f);&lt;br /&gt;            System.out.println("bits: " + toString(bits));&lt;br /&gt;            final boolean new_b = booleanFromByte(bits);&lt;br /&gt;            System.out.println("new boolean: " + new_b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final boolean b_t = true;&lt;br /&gt;            System.out.println("boolean true: " + b_t);&lt;br /&gt;            final byte bits = booleanToByte(b_t);&lt;br /&gt;            System.out.println("bits: " + toString(bits));&lt;br /&gt;            final boolean new_b = booleanFromByte(bits);&lt;br /&gt;            System.out.println("new boolean: " + new_b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final short s = 123;&lt;br /&gt;            System.out.println("short: " + s);&lt;br /&gt;            final byte [] bytes = shortToBytes(s);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final short new_s = shortFromBytes(bytes);&lt;br /&gt;            System.out.println("new short: " + new_s);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final int i = 12345;&lt;br /&gt;            System.out.println("int: " + i);&lt;br /&gt;            final byte [] bytes = intToBytes(i);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final int new_i = intFromBytes(bytes);&lt;br /&gt;            System.out.println("new int: " + new_i);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final long l = 123456789012345L;&lt;br /&gt;            System.out.println("long: " + l);&lt;br /&gt;            final byte [] bytes = longToBytes(l);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final long new_l = longFromBytes(bytes);&lt;br /&gt;            System.out.println("new long: " + new_l);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final float f = 12345.6789e-2f;&lt;br /&gt;            System.out.println("float: " + f);&lt;br /&gt;            final byte [] bytes = floatToBytes(f);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final float new_f = floatFromBytes(bytes);&lt;br /&gt;            System.out.println("new float: " + new_f);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final double d = 123456789.0123456789e-7;&lt;br /&gt;            System.out.println("double: " + d);&lt;br /&gt;            final byte [] bytes = doubleToBytes(d);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final double new_d = doubleFromBytes(bytes);&lt;br /&gt;            System.out.println("new double: " + new_d);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        {&lt;br /&gt;            System.out.println("----------------------------------------");&lt;br /&gt;            final String s = "Hello World!";&lt;br /&gt;            System.out.println("string: " + s);&lt;br /&gt;            final byte [] bytes = stringToBytes(s);&lt;br /&gt;            System.out.println("byte array: " + toString(bytes));&lt;br /&gt;            final String new_s = stringFromBytes(bytes);&lt;br /&gt;            System.out.println("new string: " + new_s);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-4674268386481272706?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/4674268386481272706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=4674268386481272706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4674268386481272706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4674268386481272706'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2010/12/conversion-utilities-in-java.html' title='Conversion utilities in Java'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7740513137599337899</id><published>2010-05-19T10:51:00.001+03:00</published><updated>2010-05-19T10:52:42.854+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='middleware'/><category scheme='http://www.blogger.com/atom/ns#' term='MUSIC-IST'/><category scheme='http://www.blogger.com/atom/ns#' term='context plug-ins'/><category scheme='http://www.blogger.com/atom/ns#' term='adaptive software'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile computing'/><title type='text'>Making "MUSIC"</title><content type='html'>The &lt;i&gt;Self-adapting applications for mobile users in ubiquitous Computing Environments&lt;/i&gt; (MUSIC) project I have been working on for the last 3.5 years is coming to an end (at least its EU-funded period). CORDIS has posted a nice review of the project, that I attach below. I am particularly proud to see a link to the &lt;i&gt;context plug-ins repository&lt;/i&gt;&amp;nbsp;which I prepared :-)&lt;br /&gt;&lt;br /&gt;The project webpage is:&amp;nbsp;&lt;a href="http://ist-music.berlios.de/site/"&gt;http://ist-music.berlios.de/site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I copy from ICT Results page (&lt;a href="http://cordis.europa.eu/ictresults"&gt;http://cordis.europa.eu/ictresults&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;Adaptive software – a late bloomer&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Adaptive software is the largely unfulfilled promise of mobile technology, but now a new platform developed by European researchers promises to finally deliver software that reconfigures itself depending on the context.&lt;br /&gt;Adaptive software – software that can configure itself automatically to deliver the maximum functionality for a given context – is finally coming. One of the long-promised fruits of the mobile technology tree, adaptation has proven a late bloomer, in large part due to the number of extremely tough problems that dog the idea.&lt;br /&gt;&lt;br /&gt;For starters, there are thousands of different potential devices, from mobile phones to media players to computers. Added to that are the even vaster number of applications.&lt;br /&gt;&lt;br /&gt;“The MUSIC project wanted to create a platform for adaptive applications that could work on any device and with any software,” explains Geir Horn, researcher with SINTEF in Norway and coordinator of the project. “[It’s] because people often want software to work differently in different contexts.”&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Faulty defaults&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;For example, most emailing software downloads each email with all attachments in the order they were received. On a slow internet connection, it can mean waiting an hour or more to retrieve all the emails a user has received, and the connection could even drop out before the important last mail has been downloaded.&lt;br /&gt;&lt;br /&gt;But email clients have a ‘slow connection’ setting that lets users download just the basic information: the subject, the sender and the size of the file, and it can be very useful when roaming data feeds or when the bandwidth is limited.&lt;br /&gt;&lt;br /&gt;And it is not just download options that can be optimised for particular contexts. Encryption, too, can be usefully adjusted for office use or when on the move, with simple or even no encryption for the office, but extremely strong encryption outside the office.&lt;br /&gt;&lt;br /&gt;Functions like these are typically buried behind obscure menu items and several dialogue boxes, and there are literally hundreds of possible options for all the different software on one device, and even more options for other devices. Users would quickly become overwhelmed if they have to change settings manually.&lt;br /&gt;&lt;br /&gt;“Of course, the email software developers could write their software so that it adapts when the internet connection is slow, or when the user is moving, or when the user is in a particular location, but there are possibly hundreds of different situations that they would need to think of, and it quickly gets prohibitively expensive,” stresses Horn. “And that is just for one application.”&lt;br /&gt;&lt;br /&gt;MUSIC handles all these issues. It takes account of a user’s location, whether it is at home, the office, in a car or on public transport. It notes the device in use, whether a mobile phone, netbook or desktop, and it is aware of dozens of other variables, from the strength of the internet connection to the time of day, from light levels to the condition of the battery.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Good guesses&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;By combining all this information, the MUSIC middleware can make a very good guess of the users’ context, what the user will want to do at a particular time, in a specific location with a given device.&lt;br /&gt;&lt;br /&gt;The MUSIC platform does not need to be configured by the user, it derives its possible settings from the high-level behaviour descriptions that are part of most software developed today. High-level behaviours describe functions such as displaying SMS messages via text or using audio.&lt;br /&gt;&lt;br /&gt;These descriptions tell the MUSIC software what settings can be altered, and MUSIC then simply uses the most appropriate settings for a given context. In the SMS example, it would render the message in text when the user is in a restaurant, but render it in audio when he or she is in a car.&lt;br /&gt;&lt;br /&gt;“The biggest challenge that the MUSIC consortium faced was trying to create software that would install on any device, whether it is a mobile phone, PDA, netbook or server,” Horn relates. “In the end, we decided to use Java, which we thought was the most appropriate cross-platform development language.”&lt;br /&gt;&lt;br /&gt;The developers also used a plugin paradigm so the software can be extended in useful ways. For example, any software can take advantage of MUSIC functionality simply by developing a plugin for the platform. Similarly, the platform can expand its functionality via plugins too.&lt;br /&gt;&lt;br /&gt;So while the base MUSIC configuration may take account of location via GPS and time via the device clock, plugins could expand the base configuration to take advantage of other sensors, such as a compass, accelerometer or light meter.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mission accomplished&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;The MUSIC project achieved all its design goals and has created a robust prototype platform. The software is designated open source and is freely available. There is a fledgling development community coalescing around the platform and, while there is no formal commercialisation plan as such, it is very likely that MUSIC will slowly, almost surreptitiously, become part of the mobile landscape.&lt;br /&gt;&lt;br /&gt;That is because the platform is tiny, just a few hundred kilobytes in its base configuration. “So if a company wants to offer services that depend on MUSIC, they can just bundle the software with the service,” Horn remarks.&lt;br /&gt;&lt;br /&gt;He offers the example of a tourist office in, say, Turin. The tourism office can develop a package that will show users specific information at a precise location – say the history of a famous church – when the user is standing there.When the user subscribes to the service, the software can be downloaded to their phone directly. That makes the MUSIC functionality available to any other MUSIC-enabled software on the user’s phone.&lt;br /&gt;&lt;br /&gt;By degrees and utility, then, MUSIC has a very strong chance of becoming a very common platform and then, finally, mobile technology will evolve to become truly ‘adaptive’.&lt;br /&gt;&lt;br /&gt;The MUSIC project received funding from the ICT strand of the EU’s Sixth Framework Programme for research.&lt;br /&gt;&lt;br /&gt;Check out the&lt;a href="http://www.ist-music.eu/developer-zone/context-plug-ins-repository-1/context-plug-ins-repository-list"&gt; plugins repository&lt;/a&gt; on the MUSIC website.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7740513137599337899?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7740513137599337899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7740513137599337899' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7740513137599337899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7740513137599337899'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2010/05/making-music.html' title='Making &quot;MUSIC&quot;'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-4607549148074667967</id><published>2010-03-04T10:15:00.000+02:00</published><updated>2010-03-04T10:15:39.432+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Geosensing'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Geosensing for your Windows 7</title><content type='html'>If you enjoy your Windows 7 and you would like to add some geosensing capabilities (especially if you travel a lot), I suggest you read this article from lifehacker:&amp;nbsp;&lt;a href="http://m.lifehacker.com/site?t=-5CdYcL9-QMUTs5DQh36Fw&amp;amp;sid=lifehackerip"&gt;How to Add Location Awareness to Your Windows 7 PC&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you do choose to install the &lt;a href="http://www.geosenseforwindows.com/"&gt;Geosense for Windows&lt;/a&gt; software, please make sure that you carefully read the installation guidelines (including the terms of use). You will be surprisingly amused :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-4607549148074667967?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/4607549148074667967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=4607549148074667967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4607549148074667967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4607549148074667967'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2010/03/geosensing-for-your-windows-7.html' title='Geosensing for your Windows 7'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7587385639185638803</id><published>2010-01-05T20:22:00.000+02:00</published><updated>2010-01-05T20:22:55.823+02:00</updated><title type='text'>Android LiveBlog</title><content type='html'>I am following my first LiveBlog:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande', Tahoma, Verdana, sans-serif; font-size: 12px; line-height: 20px;"&gt;Google Nexus One event on&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: medium; line-height: normal;"&gt;&lt;a href="http://live.gizmodo.com/"&gt;http://live.gizmodo.com/&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande', Tahoma, Verdana, sans-serif; font-size: 12px; line-height: 20px;"&gt;. Extremely entertaining and fun (even before the "actual event" had started). I am looking forward to more LiveBlogs in the future.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7587385639185638803?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7587385639185638803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7587385639185638803' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7587385639185638803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7587385639185638803'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2010/01/android-liveblog.html' title='Android LiveBlog'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7560569419813784271</id><published>2009-12-17T14:57:00.003+02:00</published><updated>2009-12-17T15:05:05.529+02:00</updated><title type='text'>Capitalism meets Socialism</title><content type='html'>Translating the sign on the window (from Greek): "&lt;a href="http://en.wikipedia.org/wiki/Coop"&gt;Cooperative&lt;/a&gt; Bank for Banker Employees of Cyprus".&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_C_OJecKV4yM/Syoq7KcV8SI/AAAAAAAAMcE/rn2NMbrnyYU/s1600-h/16122009.jpg" style="text-decoration: none;"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/_C_OJecKV4yM/Syoq7KcV8SI/AAAAAAAAMcE/rn2NMbrnyYU/s320/16122009.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5416188697770324258" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7560569419813784271?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7560569419813784271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7560569419813784271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7560569419813784271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7560569419813784271'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/12/capitalism-meets-socialism.html' title='Capitalism meets Socialism'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_C_OJecKV4yM/Syoq7KcV8SI/AAAAAAAAMcE/rn2NMbrnyYU/s72-c/16122009.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-8312427098781090549</id><published>2009-10-16T08:15:00.003+03:00</published><updated>2009-10-16T08:40:47.149+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='IntelliJ'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='IDEA'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='JetBrains'/><title type='text'>IntelliJ IDEA goes open-source</title><content type='html'>As a long time &lt;a href="http://java.com"&gt;Java fan&lt;/a&gt; and &lt;a href="http://java.sun.com"&gt;Java developer&lt;/a&gt;, I was excited to read &lt;a href="http://blogs.jetbrains.com/idea/2009/10/intellij-idea-open-sourced/"&gt;this blog announcement&lt;/a&gt; this morning. IntelliJ IDEA goes open-source with its &lt;a href="http://www.jetbrains.com/idea/nextversion/free_java_ide.html"&gt;IntelliJ IDEA Community Edition&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I started using IntelliJ IDEA while at my first real job, Eternal Systems, Inc., back in 2002. At the time, IDEA was superb and much better than any other Java IDE (probably than any IDE). I have just started playing with the community edition (version 9.0-beta) and it seems that JetBrains has kept up the good work. If you are a Java developer, I highly recommend you test out this IDE. Have a look at &lt;a href="http://www.jetbrains.com/idea/training/demos/CE/introduction_to_community_edition.html"&gt;this video&lt;/a&gt; for a quick glimpse.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While individuals will certainly benefit from this release, I think JetBrains will too. In particular, I believe that programming teachers will pick up this IDE as a recommended tool for their students who make their first steps in programming. With its constant and real-time code inspections, IDEA will be a great educational resource and students will not forget it after they graduate.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-8312427098781090549?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/8312427098781090549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=8312427098781090549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8312427098781090549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8312427098781090549'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/10/intellij-idea-goes-open-source.html' title='IntelliJ IDEA goes open-source'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-8608604524239178382</id><published>2009-10-11T17:40:00.008+03:00</published><updated>2009-10-13T08:23:25.904+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile platforms'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='context-aware'/><title type='text'>Time for Android!</title><content type='html'>One of my main resolutions for after I would get done with my PhD thesis was to get deeper into the details of the architecture and the underlying mechanisms of &lt;a href="http://www.android.com/"&gt;Android&lt;/a&gt;. Now that my defense was completed successfully (with only a few minor improvements pending), I am ready for what I believe will be an exciting journey.&lt;br /&gt;&lt;br /&gt;As a researcher in software engineering for context-aware systems, Android seems to be a unique opportunity. Here is what I believe makes the &lt;a href="http://developer.android.com/"&gt;Android platform&lt;/a&gt; stand out from the rest of the mobile platforms:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It is &lt;strong&gt;open&lt;/strong&gt;. This is a huge difference from its main competition, particularly the iPhone. While the latter is an excellent platform, and probably the state-of-the-art in the current arena of smart-phone hardware, its future is a bit uncertain. As a closed platform, the iPhone might face great challenges in attracting developers and end-users when other platforms (like the Android) catch-up with it.&lt;/li&gt;&lt;li&gt;Its &lt;strong&gt;architecture &lt;/strong&gt;is well thought. With a layered structure that facilitates platform independence (i.e., the Linux kernel), powerful common libraries (e.g., realizing accelerated graphics and security protocols) and a runtime layer that allows development in Java (one of the most successful and widely &lt;em&gt;mastered&lt;/em&gt; programming languages). With this, building for Android is a breeze and fun process!&lt;/li&gt;&lt;li&gt;It features &lt;strong&gt;reusable and replaceable components&lt;/strong&gt;. This means that anyone can develop applications that feature web-browser and map views (among others) without having to develop them. It also means that any developer is free to enter an open market and compete with others (including Google itself) on providing the best core applications, like a phone manager or contacts manager.&lt;/li&gt;&lt;li&gt;It features an &lt;strong&gt;open market&lt;/strong&gt;. While all registered applications must qualify a set of rules in order to be listed, these are much more relaxed and &lt;em&gt;open&lt;/em&gt; in comparison to iPhone's market-place, which prohibits listing applications that compete with those from Apple.&lt;/li&gt;&lt;li&gt;It provides good &lt;strong&gt;developer tools&lt;/strong&gt;. The &lt;a href="http://developer.android.com/sdk"&gt;Android SDK&lt;/a&gt; is of free to download and use (as expected), while the developers can also benefit from a great deal of online resources.&lt;/li&gt;&lt;li&gt;It is &lt;b&gt;Google-backed&lt;/b&gt;. As the search giant is the core promoter in the &lt;a href="http://www.openhandsetalliance.com/"&gt;Open Handset Alliance&lt;/a&gt;, the Android users can feel safe that the web-apps they are so accustomed to (like GMail, GCalendar, etc) will always be supported on their devices. Furthermore, building on their &lt;a href="http://www.google.com/corporate"&gt;great legacy with organizing the world's information&lt;/a&gt;, the Android users can expect more innovative applications and functionality in their phones, assisting them to organize their own, mobile world.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I recommend the following three tutorials for anyone who needs to get a quick (but very intuitive) look into Android:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=QBGfUs9mQYY&amp;amp;feature=player_embedded"&gt;Part 1 of 3 - Architecture Overview&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=fL6gSd4ugSI&amp;amp;feature=player_embedded"&gt;Part 2 of 3 - Application lifecycle &lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=MPukbH6D-lY&amp;amp;feature=player_embedded"&gt;Part 3 of 3 - APIs&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Update October 13, 2009: Just read &lt;a href="http://news.slashdot.org/story/09/10/12/1341218/Android-Application-Development"&gt;this interesting post&lt;/a&gt; on Slashdot.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-8608604524239178382?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/8608604524239178382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=8608604524239178382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8608604524239178382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8608604524239178382'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/10/ready-or-not-android-here-i-come.html' title='Time for Android!'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-2551209311315093889</id><published>2009-09-08T12:07:00.004+03:00</published><updated>2009-09-08T12:40:58.660+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TV'/><category scheme='http://www.blogger.com/atom/ns#' term='CSI'/><category scheme='http://www.blogger.com/atom/ns#' term='Cyprus'/><title type='text'>CSI Cyprus</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/CSI:_Crime_Scene_Investigation"&gt;Crime Scene Investigation&lt;/a&gt; (CSI) is a quite popular TV series dealing with crimes (of course) and their forensic investigation. The series is quite popular and older seasons of the &lt;a href="http://en.wikipedia.org/wiki/CSI_(franchise)"&gt;franchise&lt;/a&gt; are broadcasted (and assumingly are popular) in Cyprus too. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interestingly, Cyprus also serves a central role in the drama's script in episode 25 of the latest season (&lt;a href="http://en.wikipedia.org/wiki/List_of_CSI:_NY_episodes#Season_6:_2009-2010"&gt;season 6&lt;/a&gt;) in &lt;a href="http://en.wikipedia.org/wiki/CSI:_NY"&gt;CSI: New York&lt;/a&gt;. If you cannot wait for season 6 episode 25 to be released, then try downloading the teaser video from iTunes. You will be amused!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This reminds me of another great moment from the US pop-cult industry. In season 16 of the Simpsons, Homer shouts to a Turk captain: "&lt;a href="http://www.cyprus-mail.com/news/main.php?id=19123&amp;amp;cat_id=1"&gt;... you Cyprus-splitting jerks!&lt;/a&gt;". I was very proud to share that in my &lt;a href="http://www.phigita.net/~nearchos/blog/41"&gt;Greek blog&lt;/a&gt; back then.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Speaking of Homer, I also watched the teaser for season 21 (!) of the Simpsons (also available in iTunes for free), and it seems that these guys will never run out of ideas! &lt;a href="http://en.wikipedia.org/wiki/Homer_simpson"&gt;His&lt;/a&gt; Odyssey will run a really long time!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-2551209311315093889?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/2551209311315093889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=2551209311315093889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2551209311315093889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2551209311315093889'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/09/csi-cyprus.html' title='CSI Cyprus'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-8889405685525866023</id><published>2009-02-12T09:47:00.021+02:00</published><updated>2009-05-25T15:04:29.864+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development methodology'/><category scheme='http://www.blogger.com/atom/ns#' term='CaMP'/><category scheme='http://www.blogger.com/atom/ns#' term='Context-aware Media Player'/><title type='text'>Developing a complete context-aware application (CaMP) - Tutorial 10</title><content type='html'>This tutorial continues the &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series&lt;/a&gt; started a few weeks back, with a comprehensive example: developing the &lt;span style="font-style: italic;"&gt;Context-aware Media Player&lt;/span&gt; (CaMP). Here, we describe and apply a development methodology, which details the steps required to design and implement a context-aware application using the MUSIC middleware.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Development methodology&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following steps describe a structured method for designing and implementing context-aware applications using the MUSIC Context System. It is recommended that before you try to follow this methodology, you study the Tutorials on the MUSIC Context System &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The methodology consists of the following 6 steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Identify the relevant context types; in case some context types are higher-level, identify other elementary context types to build on them&lt;/li&gt;&lt;li&gt;For each elementary context type identify a “context sensor” plug-in and for each high-level context type identify a “context reasoner”&lt;/li&gt;&lt;li&gt;For each context plug-in, reuse an existing implementation or proceed to construct a new one&lt;/li&gt;&lt;li&gt;Develop the functional aspects of your application&lt;/li&gt;&lt;li&gt;Register your application to the relevant context types and implement the code that adapts the application accordingly&lt;/li&gt;&lt;li&gt;Pack your application in JAR file as per OSGi's bundle packaging specification&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Furthermore, step 3 is also analyzed into the following sub-steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Implement (or reuse) the corresponding context model&lt;/li&gt;&lt;li&gt;Define the MANIFEST and XML descriptor of the “context plug-in”&lt;br /&gt;2.1. Define the standard properties like you would do for an OSGi component&lt;br /&gt;2.2. Define the “provided” context types&lt;br /&gt;2.3. Define the “required” context types [optional step for context reasoners]&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Extend the abstract context sensor or context reasoner&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Implement the “activate” and “deactivate” methods to start and stop the generation of context events respectively&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Implement the “contextChanged” method to handle received context events [optional step for context reasoners]&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pack everything in a JAR file, as per the OSGi’s bundle packaging specification&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Applying the development methodology to the &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Context-aware Media Player&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; (CaMP)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;Context-aware Media Player&lt;/span&gt; is a simple application, which is defined as follows:&lt;br /&gt;&lt;br /&gt;"&lt;span style="font-style: italic;"&gt;CaMP is a simple media player, capable of playing audio or video media tracks, while exhibiting the following context-aware behavior:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;When the user is detected as entering the room (where CaMP is deployed), then resume playback&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;When the user is detected as exiting the room, then pause playback&lt;/span&gt;"&lt;/li&gt;&lt;/ul&gt;We are going to develop an application that exhibits this kind of context-aware behavior using the proposed development methodology.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Identify the relevant context types; in case some context types are higher level, identify other elementary context types to build on them&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first step is to analyze the relevant context types. In this case, the task it is easy because the application's verbal description is quite straight-forward. The main context type we are interested in is "whether the user is in the room". Thus we define the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; context type. This is a rather high-level context type, so we need to further refine it and decide how we can derive this context type.&lt;br /&gt;&lt;br /&gt;While multiple approaches are possible, assume the following one: a user is assumed to have entered the room when his Bluetooth smart-phone is detected while at the same time some motion is detected by the web-camera on the deployment computer. Thus, we define two additional, elementary context types: &lt;span style="font-style: italic;"&gt;Bluetooth devices&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Motion&lt;/span&gt;. These two are combined to &lt;span style="font-style: italic;"&gt;infer&lt;/span&gt; whether the user has entered (or exited) the room where CaMP is deployed.&lt;br /&gt;&lt;br /&gt;The hierarchy of the context types is illustarted in the following figure:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/ContextTypesAndContextPlugins.PNG" title="The hierarchy of the context types and the corresponding context plug-ins"&gt;&lt;br /&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/ContextTypesAndContextPlugins.PNG" alt="The hierarchy of the context types and the corresponding context plug-ins" border="0" width="640" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Step 2: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;For each elementary context type identify a “context sensor” plug-in and for each high-level context type identify a “context reasoner”&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The second step is to define a context plug-in for each context type. This comes naturally from the hierarchy of the context types, as illustrated in the figure above.&lt;br /&gt;&lt;br /&gt;To detect the attached Bluetooth devices, we define a &lt;span style="font-style: italic;"&gt;Bluetooth Sensor&lt;/span&gt; plug-in.&lt;br /&gt;To detect motion in the room, we define the &lt;span style="font-style: italic;"&gt;Motion Sensor&lt;/span&gt; plug-in&lt;br /&gt;Finally, to detect whether the user has entered or exited the room, we define a context reasoner that takes input from the other two plug-ins; the &lt;span style="font-style: italic;"&gt;User-in-the-Room Sensor&lt;/span&gt; plug-in&lt;br /&gt;&lt;br /&gt;Notably, while the first two sensors have no context input (other than what is sensed from hardware, like the Bluetooth adaptor or the web-camera), the third one depends on input context types only. Thus, the first two can be constructed as context sensors and the third one as context reasoner.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;For each context plug-in, reuse an existing implementation or proceed to construct a new one&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The next step is to reuse or develop a new plug-in for each one identified. As the construction of context sensors has already been covered extensively in &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;Tutorial 8&lt;/a&gt;, we will here cover just the development of the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; context reasoner plug-in.&lt;br /&gt;&lt;br /&gt;At this point, it should be noted that while a context plug-in is simply required to implement the IContextPlugin interface, it is usually more convenient to extend one of the helper abstract classes which provide default code for much of the required functionality. This functionality is illustrated in the following figure:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/ContextPluginsHierarchy.PNG" title="Hierarchy of helper abstract classes for building context plug-ins"&gt;&lt;br /&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/ContextPluginsHierarchy.PNG" alt="Hierarchy of helper abstract classes for building context plug-ins" width="640" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For instance, a class extending the AbstractContextPlugin can simply implement the &lt;span style="font-style: italic;"&gt;activate()&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;deactivate()&lt;/span&gt; methods to start and stop generating events accordingly. The generated events are delegated to the context middleware via the &lt;span style="font-style: italic;"&gt;fireContextChangedEvent()&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;On the other hand, a class extending the AbstractContextReasonerPlugin can simply implement the &lt;span style="font-style: italic;"&gt;contextChanged()&lt;/span&gt; method to receive and handle context change events. The &lt;span style="font-style: italic;"&gt;activate()&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;deactivate()&lt;/span&gt; methods are already implemented, and automatically register the context plug-in for notification of relevant context events (as defined in the XML service descriptor). (In case you need to overload the &lt;span style="font-style: italic;"&gt;activate()&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;deactivate&lt;/span&gt; methods, make sure that you delegate the call to the super-class as well, &lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;super.activate()&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;super.deactivate()&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;In both the cases of extending the AbstractContextPlugin and AbstractContextReasonerPlugin, the developers should define the &lt;span style="font-style: italic;"&gt;provided&lt;/span&gt; (and optionally the &lt;span style="font-style: italic;"&gt;required&lt;/span&gt;) context types as it is illustrated here:&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="UserInTheRoom" immediate="true"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.context.user_in_the_room.plugin.UserInTheRoomSensor"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;service&amp;gt;&lt;br /&gt;&amp;lt;provide interface="org.istmusic.mw.context.plugins.IContextPlugin"/&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPES" value="user-in-the-room"/&amp;gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPE_ENTITY[user-in-the-room]" value="#concepts.entities.environment|room"/&amp;gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPE_SCOPE[user-in-the-room]" value="#concepts.scopes.abstract.user_in_the_room"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name="REQUIRED_CONTEXT_TYPES" value="motion bluetooth"/&amp;gt;&lt;br /&gt;&amp;lt;property name="REQUIRED_CONTEXT_TYPE_ENTITY[motion]" value="#concepts.entities.environment|room"/&amp;gt;&lt;br /&gt;&amp;lt;property name="REQUIRED_CONTEXT_TYPE_SCOPE[motion]" value="#concepts.scopes.abstract.motion_detected"/&amp;gt;&lt;br /&gt;&amp;lt;property name="REQUIRED_CONTEXT_TYPE_ENTITY[bluetooth]" value="#concepts.entities.device|this"/&amp;gt;&lt;br /&gt;&amp;lt;property name="REQUIRED_CONTEXT_TYPE_SCOPE[bluetooth]" value="#concepts.scopes.resources.network.bluetooth"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In practice, you first define some aliases for each provided (or required) context type, and then you define the &lt;span style="font-style: italic;"&gt;entity&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;scope&lt;/span&gt; for each one of those accordingly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing the &lt;span style="font-style: italic;"&gt;User-in-the-Room &lt;/span&gt;Context Reasoner Plug-in&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To develop the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; context reasoner plug-in, we also follow the steps defined in the methodology.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.1: &lt;/span&gt;&lt;span style="font-style: italic;"&gt;Implement (or reuse) the corresponding context model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this step, we need to define the model for the User-in-the-Room context type. As such, we first identify the required context values. In this case, we can simply abstract this type of information with a simple &lt;span style="font-style: italic;"&gt;boolean&lt;/span&gt;. Following a process like the one described in &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;Tutorial 7&lt;/a&gt;, we conclude to a model as illustrated in the following figure.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/User-in-the-RoomContextModel.PNG" title="User-in-the-Room Context Model"&gt;&lt;br /&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/User-in-the-RoomContextModel.PNG" alt="User-in-the-Room Context Model" border="0" width="640" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.2:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Define the MANIFEST and XML descriptor of the Context Plug-in&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The MANIFEST for the context reasoner plug-in is defined just like it is defined for any other OSGi component. In our case, the resulting file is illustrated in the following:&lt;br /&gt;&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: User-in-the-room sensor context plugin&lt;br /&gt;Bundle-SymbolicName: UserInTheRoomSensor&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Bundle-ClassPath: .&lt;br /&gt;Import-Package: org.istmusic.mw.context.plugins,&lt;br /&gt;org.istmusic.mw.context.events,&lt;br /&gt;org.istmusic.mw.context.util.scheduler,&lt;br /&gt;org.istmusic.mw.context.model.api,&lt;br /&gt;org.istmusic.mw.context.model.impl,&lt;br /&gt;org.istmusic.mw.context.model.impl.values,&lt;br /&gt;org.istmusic.mw.context.ontologies,&lt;br /&gt;cy.ac.ucy.cs.osgi.context.bluetooth.model,&lt;br /&gt;cy.ac.ucy.cs.osgi.context.motion.model,&lt;br /&gt;javax.swing&lt;br /&gt;Export-Package: cy.ac.ucy.cs.osgi.context.user_in_the_room.model&lt;br /&gt;Service-Component: OSGI-INF/UserInTheRoomSensor.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next, the service descriptor is defined. As it was discuess in the previous paragraphs, this step requires that the &lt;span style="font-style: italic;"&gt;provided&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;required&lt;/span&gt; context types are explicitly defined. In the case of the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; plug-in, the service descriptor was already illustrated in the previous paragraphs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.3:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Extend the abstract context sensor or context reasoner&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; has been identified as a context reasoner, we extend the AbstractContextReasonerPlugin class. The code of the UserInTheRoomSensor class is illustrated in the following:&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.context.user_in_the_room.plugin;&lt;br /&gt;&lt;br /&gt;import org.istmusic.mw.context.plugins.AbstractContextReasonerPlugin;&lt;br /&gt;import org.istmusic.mw.context.events.ContextChangedEvent;&lt;br /&gt;import org.istmusic.mw.context.model.api.IContextElement;&lt;br /&gt;import cy.ac.ucy.cs.osgi.context.motion.model.MotionContextElement;&lt;br /&gt;import cy.ac.ucy.cs.osgi.context.bluetooth.model.BluetoothContextElement;&lt;br /&gt;import cy.ac.ucy.cs.osgi.context.user_in_the_room.model.UserInTheRoomContextElement;&lt;br /&gt;&lt;br /&gt;public class UserInTheRoomSensor extends AbstractContextReasonerPlugin&lt;br /&gt;{&lt;br /&gt;public static final String PLUGIN_ID = "User-in-the-room Sensor";&lt;br /&gt;&lt;br /&gt;public static final double THRESHOLD = 0.12d;&lt;br /&gt;public static final long MOTION_VALIDITY_PERIOD = 15000L; // 15 seconds&lt;br /&gt;&lt;br /&gt;public UserInTheRoomSensor()&lt;br /&gt;{&lt;br /&gt; super(PLUGIN_ID);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private boolean userInTheRoom = false;&lt;br /&gt;private boolean userBluetoothDeviceAttached = false;&lt;br /&gt;&lt;br /&gt;public void deactivate()&lt;br /&gt;{&lt;br /&gt; userInTheRoom = false;&lt;br /&gt; userBluetoothDeviceAttached = false;&lt;br /&gt; super.deactivate();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private long lastMotionTimestamp = 0L;&lt;br /&gt;&lt;br /&gt;public void contextChanged(ContextChangedEvent event)&lt;br /&gt;{&lt;br /&gt; IContextElement [] contextElements = event.getContextDataset().getContextElements();&lt;br /&gt;&lt;br /&gt; for(int i = 0; i &amp;lt; contextElements.length; i++)&lt;br /&gt; {&lt;br /&gt;     final IContextElement contextElement = contextElements[i];&lt;br /&gt;     if(contextElement instanceof MotionContextElement)&lt;br /&gt;     {&lt;br /&gt;         lastMotionTimestamp = System.currentTimeMillis();&lt;br /&gt;     }&lt;br /&gt;     else if (contextElement instanceof BluetoothContextElement)&lt;br /&gt;     {&lt;br /&gt;         BluetoothContextElement bluetoothContextElement = (BluetoothContextElement) contextElement;&lt;br /&gt;         userBluetoothDeviceAttached = bluetoothContextElement.contains(UserInTheRoomVisualComponent.DEFAULT_USER_DEVICE_ID);&lt;br /&gt;     }&lt;br /&gt;     // else ignore&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; final boolean motionDetectedRecently = lastMotionTimestamp + MOTION_VALIDITY_PERIOD &amp;gt; System.currentTimeMillis();&lt;br /&gt; if(motionDetectedRecently &amp;amp;&amp;amp; userBluetoothDeviceAttached)&lt;br /&gt; {&lt;br /&gt;     if(!userInTheRoom)&lt;br /&gt;     {&lt;br /&gt;         userInTheRoom = true;&lt;br /&gt;         UserInTheRoomContextElement userInTheRoomContextElement = new UserInTheRoomContextElement(PLUGIN_ID, userInTheRoom);&lt;br /&gt;         fireContextChangedEvent(this, userInTheRoomContextElement);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt; else if(!userBluetoothDeviceAttached)&lt;br /&gt; {&lt;br /&gt;     if(userInTheRoom)&lt;br /&gt;     {&lt;br /&gt;         userInTheRoom = false;&lt;br /&gt;         UserInTheRoomContextElement userInTheRoomContextElement = new UserInTheRoomContextElement(PLUGIN_ID, userInTheRoom);&lt;br /&gt;         fireContextChangedEvent(this, userInTheRoomContextElement);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The most interesting part of this class is the implementation of the &lt;span style="font-style: italic;"&gt;contextChanged()&lt;/span&gt; method. More details about this code is provided in the following paragraphs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.4:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Implement the "activate" and "deactivate" methods to start and stop the generation of context events respectively&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this case, the two methods (&lt;span style="font-style: italic;"&gt;activate&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;deactivate&lt;/span&gt;) are not very significant because the context plug-in is triggered by input context events arriving at the &lt;span style="font-style: italic;"&gt;contextChanged()&lt;/span&gt; method (rather than timed events from a scheduler, like those defined &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;Tutorial 8&lt;/a&gt; for example).&lt;br /&gt;&lt;br /&gt;The only noteworthy observation is that the &lt;span style="font-style: italic;"&gt;deactivate()&lt;/span&gt; method is over-ridden (to initialize some local variables) but the delegation is forwarded to the super class anyway. This is important, as it was discussed already, because it allows for the automatic registration and unregistration with the context middleware.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.5:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Implement the "contextChanged" method to handle received context events [optional step for context reasoners]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As it was already argued, the most interesting part of this class is in the &lt;span style="font-style: italic;"&gt;contextChanged()&lt;/span&gt; method. In here, received events are analyzed to infer whether the detected motion and the Bluetooth's presence (or absense) should trigger an event. Once it is decided that an event needs to be triggered, the &lt;span style="font-style: italic;"&gt;fireContextChangedEvent&lt;/span&gt; helper method is invoked.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3.6:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Pack everything in a JAR file, as per the OSGi’s bundle packaging specification&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is a mandatory step for every OSGi component. The process to package the plug-in has been described in detail in the &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;previous tutorials&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This concludes the development of the &lt;span style="font-style: italic;"&gt;User-in-the-Room&lt;/span&gt; context reasoner plug-in. It is assumed that the other two plug-ins are already implemented, and we resume with the development of the CaMP application.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Develop the functional aspects of your application&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This step has no significant details. Just like in usual software development, we try to reuse existing libraries as much as possible. For example, in the case of the CaMP application, we reuse the &lt;span style="font-style: italic;"&gt;Java Media Framework&lt;/span&gt; (JMF) [1] libraries by SUN in order to avoid having to develop complex media handling code ourselves.&lt;br /&gt;&lt;br /&gt;What is important to notice however, is that with this approach it is possible to build your application with &lt;span style="font-style: italic;"&gt;Separation of Concerns&lt;/span&gt; [2]. At first, you develop the functional aspect of your application (the media playback code and the GUI in this case) and then you hook-up the context-aware behavior (see next step).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 5:&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Register your application to the relevant context types and implement the code that adapts the application accordingly&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To bind a client to the context middleware, one need to follow these steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Define your client as an OSGi component&lt;/li&gt;&lt;li&gt;Define a service descriptor with a reference to the “IContextAccess” service&lt;/li&gt;&lt;li&gt;Implement the “IContextListener” interface and define the code that will handle the asynchronous context notifications&lt;/li&gt;&lt;li&gt;Pack everything in a JAR file, as per the OSGi’s bundle packaging specification&lt;/li&gt;&lt;/ol&gt;The first step is straight-forward. As the context middleware offers its services over OSGi, the clients must also be defined and deployed as OSGi components.&lt;br /&gt;&lt;br /&gt;To enable automatic context access (using Declarative Services), the developer needs to define a reference to the &lt;span style="font-style: italic;"&gt;IContextAccess&lt;/span&gt; service in the service descriptor. For example, consider the service descriptor of the CaMP application:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="CaMP"&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;implementation class="cy.ac.ucy.cs.camp.CaMP"/&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;reference name="context_access"&lt;br /&gt;         interface="org.istmusic.mw.context.IContextAccess"&lt;br /&gt;         bind="setContextAccess"&lt;br /&gt;         unbind="unsetContextAccess"&lt;br /&gt;         cardinality="0..1"&lt;br /&gt;         policy="dynamic"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As it is illustrated in this descriptor, the IContextAccess service is referenced and appropriate binding methods are defined. The service descriptor is of course referenced by a Manifest file, as illustrated in the following figure:&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMPcomponent.PNG" title="The CaMP component"&gt;&lt;br /&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMPcomponent.PNG" alt="The CaMP component" border="0" width="640" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Finally, the actual code where the binding to the context middleware and the handling of the context events takes place is illustrated here in the following:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.camp;&lt;br /&gt;&lt;br /&gt;import org.osgi.service.component.ComponentContext;&lt;br /&gt;import org.istmusic.mw.context.IContextAccess;&lt;br /&gt;import org.istmusic.mw.context.plugins.IContextPlugin;&lt;br /&gt;import org.istmusic.mw.context.exceptions.ContextException;&lt;br /&gt;import org.istmusic.mw.context.events.IContextListener;&lt;br /&gt;import org.istmusic.mw.context.events.ContextChangedEvent;&lt;br /&gt;import org.istmusic.mw.context.ontologies.DefaultMusicOntologyV0_1;&lt;br /&gt;import org.istmusic.mw.context.model.api.IEntity;&lt;br /&gt;import org.istmusic.mw.context.model.api.IScope;&lt;br /&gt;import org.istmusic.mw.context.model.api.IContextElement;&lt;br /&gt;import org.istmusic.mw.context.model.api.IValue;&lt;br /&gt;import org.istmusic.mw.context.model.impl.values.BooleanValue;&lt;br /&gt;&lt;br /&gt;import javax.swing.*;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;import java.awt.*;&lt;br /&gt;&lt;br /&gt;public &lt;span style="font-weight: bold;"&gt;class CaMP&lt;/span&gt; extends JFrame &lt;span style="font-weight: bold;"&gt;implements IContextListener&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;public static final String DISCONNECTED = "CaMP - Disconnected from the context middleware";&lt;br /&gt;public static final String CONNECTED = "CaMP - Connected to the context middleware";&lt;br /&gt;&lt;br /&gt;public static final IEntity ENTITY = DefaultMusicOntologyV0_1.ENTITY_ENVIRONMENT_ROOM;&lt;br /&gt;public static final IScope SCOPE = DefaultMusicOntologyV0_1.SCOPE_ABSTRACT_USER_IN_THE_ROOM;&lt;br /&gt;&lt;br /&gt;private final Logger logger = Logger.getLogger(CaMP.class.getCanonicalName());&lt;br /&gt;&lt;br /&gt;private final MediaPlayer mediaPlayer;&lt;br /&gt;private final UnderTheHoodPanel underTheHoodPanel;&lt;br /&gt;private final AboutPanel aboutPanel;&lt;br /&gt;&lt;br /&gt;public CaMP()&lt;br /&gt;{&lt;br /&gt;    super("CaMP");&lt;br /&gt;&lt;br /&gt;    setLayout(new BorderLayout());&lt;br /&gt;    final JTabbedPane tabbedPane = new JTabbedPane();&lt;br /&gt;    add(tabbedPane, BorderLayout.CENTER);&lt;br /&gt;&lt;br /&gt;    mediaPlayer = new MediaPlayer();&lt;br /&gt;    tabbedPane.add("Media player", mediaPlayer.getVisualComponent());&lt;br /&gt;&lt;br /&gt;    underTheHoodPanel = new UnderTheHoodPanel();&lt;br /&gt;    tabbedPane.add("Under the hood", new JScrollPane(underTheHoodPanel));&lt;br /&gt;&lt;br /&gt;    aboutPanel = new AboutPanel();&lt;br /&gt;    tabbedPane.add("About", aboutPanel);&lt;br /&gt;&lt;br /&gt;    pack();&lt;br /&gt;    tabbedPane.updateUI();&lt;br /&gt;    setSize(400, 300);&lt;br /&gt;    setVisible(false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void activate(ComponentContext componentContext)&lt;br /&gt;{&lt;br /&gt;    logger.info("CaMP: activate");&lt;br /&gt;&lt;br /&gt;    setVisible(true);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void deactivate(ComponentContext componentContext)&lt;br /&gt;{&lt;br /&gt;    logger.info("CaMP: deactivate");&lt;br /&gt;&lt;br /&gt;    // make sure the media player is stopped&lt;br /&gt;    mediaPlayer.stop();&lt;br /&gt;&lt;br /&gt;    setVisible(false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void setContextAccess(IContextAccess contextAccess)&lt;br /&gt;{&lt;br /&gt;    logger.info("CaMP: setContextAccess");&lt;br /&gt;&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        contextAccess.addContextListener(ENTITY, SCOPE, this);&lt;br /&gt;&lt;br /&gt;        setTitle(CONNECTED);&lt;br /&gt;    }&lt;br /&gt;    catch (ContextException ce)&lt;br /&gt;    {&lt;br /&gt;        logger.severe(ce.getMessage());&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void unsetContextAccess(IContextAccess contextAccess)&lt;br /&gt;{&lt;br /&gt;    logger.info("CaMP: unsetContextAccess");&lt;br /&gt;&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        contextAccess.removeContextListener(ENTITY, SCOPE, this);&lt;br /&gt;&lt;br /&gt;        setTitle(DISCONNECTED);&lt;br /&gt;    }&lt;br /&gt;    catch (ContextException ce)&lt;br /&gt;    {&lt;br /&gt;        logger.severe(ce.getMessage());&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;contextChanged&lt;/span&gt;(ContextChangedEvent event)&lt;br /&gt;{&lt;br /&gt;    final IContextElement[] contextElements = event.getContextDataset().getContextElements();&lt;br /&gt;    for(int i = 0; i &amp;lt; contextElements.length; i++)&lt;br /&gt;    {&lt;br /&gt;        final IContextElement contextElement = contextElements[i];&lt;br /&gt;        IValue value = contextElement.getContextData().getContextValue(&lt;br /&gt;                DefaultMusicOntologyV0_1.SCOPE_ABSTRACT_USER_IN_THE_ROOM).getValue();&lt;br /&gt;        BooleanValue booleanValue = (BooleanValue) value;&lt;br /&gt;        if(booleanValue.getBooleanValue().booleanValue())&lt;br /&gt;        {&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;                mediaPlayer.start();&lt;/span&gt;&lt;br /&gt;         }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;                mediaPlayer.stop();&lt;/span&gt;&lt;br /&gt;         }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Just like in the context reasoner plug-ins, the most interesting part here is the implementation of the &lt;span style="font-style: italic;"&gt;contextChanged&lt;/span&gt; method, defined in the &lt;span style="font-style: italic;"&gt;IContextListener&lt;/span&gt; interface.&lt;br /&gt;&lt;br /&gt;The actual context-aware logic is very simple: The received events are analyzed and when an event corresponds to the user entering the room, then the media playback is resumed. Otherwise, if the received event corresponds to the user exiting the room, then the media playback is paused.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 6:&lt;/span&gt; Pack your application in JAR file as per OSGi's bundle packaging specification&lt;br /&gt;&lt;br /&gt;Of course, once the code and the artifacts are finalized, they are all compiled and packaged together in a JAR file, according to the OSGi's packaging specification.&lt;br /&gt;&lt;br /&gt;JARs of the used plug-ins, including the source code and an ANT build script, are available here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/camp/jar/CaMP.jar"&gt;CaMP.jar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/camp/jar/BluetoothSensor.jar"&gt;BluetoothSensor.jar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/camp/jar/MotionSensor.jar"&gt;MotionSensor.jar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/camp/jar/UserInTheRoomSensor.jar"&gt;UserInTheRoomSensor.jar&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/camp/jar/JMFBundle.jar"&gt;JMFBundle.jar&lt;/a&gt; (needed by the CaMP and the MotionSensor bundles)&lt;/li&gt;&lt;/ul&gt;Exact details about the requirements and the deployment method for CaMP are provided in &lt;a href="http://www.cs.ucy.ac.cy/%7Epaspalli/CaMP"&gt;this webpage&lt;/a&gt;. Finally, some screenshots of the CaMP application active are available here (click to enlarge):&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_MediaPlayer_Video.PNG" title="CaMP - Video playback"&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_MediaPlayer_Video.PNG" alt="CaMP - Video playback" border="0" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_UnderTheHood_AllSensors2.PNG" title="CaMP - Under the hood"&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_UnderTheHood_AllSensors2.PNG" alt="CaMP - Under the hood" border="0" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_About.PNG" title="CaMP - About"&gt;&lt;img src="http://www.cs.ucy.ac.cy/~paspalli/research/methodology/CaMP_About.PNG" alt="CaMP - About" border="0" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;span style="font-weight: bold;"&gt;References&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[1]. SUN Microsystems, &lt;span style="font-style: italic;"&gt;Java Media Framework&lt;/span&gt; (JMF), &lt;a href="http://java.sun.com/javase/technologies/desktop/media/jmf"&gt;http://java.sun.com/javase/technologies/desktop/media/jmf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;[2]. Nearchos Paspallis, Frank Eliassen, Svein Hallsteinsen, and George A. Papadopoulos, &lt;span style="font-weight: bold;"&gt;Developing Self-Adaptive Mobile Applications and Services with Separation-of-Concerns&lt;/span&gt;, &lt;a href="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;amp;tid=11752"&gt;At Your Service: Service-Oriented Computing from an EU Perspective&lt;/a&gt;, E. Di Nitto, A-M. Sassen, O. Traverso and A. Zwegers (eds), MIT Press, June 2009, chapter 6, pp. 129-158&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-8889405685525866023?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/8889405685525866023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=8889405685525866023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8889405685525866023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8889405685525866023'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/02/developing-complete-context-aware.html' title='Developing a complete context-aware application (CaMP) - Tutorial 10'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7115678114509726032</id><published>2009-01-30T10:33:00.000+02:00</published><updated>2009-01-29T14:26:44.276+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='context clients'/><category scheme='http://www.blogger.com/atom/ns#' term='context plug-ins'/><title type='text'>Developing a context client - Tutorial 9</title><content type='html'>This is the next post in the &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series of tutorials&lt;/a&gt; that introduces OSGi and the MUSIC Context System. The &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;previous tutorial&lt;/a&gt;, described how to develop a context sensor plug-in, that monitors the memory use and periodically generates events containing data about the last measurements. This tutorial describes how to develop a context client that &lt;span style="font-style: italic;"&gt;listens&lt;/span&gt; for changes to the memory context type.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing the Memory Viewer context client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As usual, a memory viewer is first a normal OSGi component bundle. We described how to create components and bind them with services in the &lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;second&lt;/a&gt; and the &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;third&lt;/a&gt; tutorials. As such, to develop a context client we need to specify three parts:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Define its Manifest&lt;/span&gt;: The Manifest describes the properties of the bundle. As such it defines the &lt;span style="font-style: italic;"&gt;imported &lt;/span&gt;and possibly &lt;span style="font-style: italic;"&gt;exported &lt;/span&gt;packages and it also provides a pointer to the service descriptor.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Define its service descriptor XML file&lt;/span&gt;: In the case of a context client, the service descriptor is simply used to define the &lt;span style="font-style: italic;"&gt;needed&lt;/span&gt; IContextAccess service (which it was introduced in &lt;a href="http://nearchos.blogspot.com/2009/01/introduction-to-music-context-system.html"&gt;this tutorial&lt;/a&gt;).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Define the code that implements the context client&lt;/span&gt;: The code of the context client is implemented in one or more classes. In principle, a context client implements the IContextListener interface which allows it to asynchronously access context data.&lt;/li&gt;&lt;/ul&gt;For example, the development of the memory context client results to the following parts:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Memory viewer client for the MUSIC Context System&lt;br /&gt;Bundle-SymbolicName: MemoryViewer&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Bundle-ClassPath: .&lt;br /&gt;Import-Package: org.istmusic.mw.context,&lt;br /&gt;org.istmusic.mw.context.exceptions,&lt;br /&gt;org.istmusic.mw.context.events,&lt;br /&gt;org.istmusic.mw.context.ontologies,&lt;br /&gt;org.istmusic.mw.context.model.api,&lt;br /&gt;cy.ac.ucy.cs.osgi.tutorial7.memory_model&lt;br /&gt;Service-Component: OSGI-INF/MemoryViewer.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As a typical OSGi component, its Manifest defines imported and exported packages and a pointer to the service descriptor XML file. In this case, the service descriptor is named "MemoryViewer" and is as follows:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="MemoryViewer" immediate="true"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial9.MemoryViewer"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- Reference to the context access service --&amp;gt;&lt;br /&gt;&amp;lt;reference name="context.access"&lt;br /&gt;   interface="org.istmusic.mw.context.IContextAccess"&lt;br /&gt;   cardinality="1..1"&lt;br /&gt;   bind="setContextAccessService"&lt;br /&gt;   unbind="unsetContextAccessService"&lt;br /&gt;   policy="dynamic"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The most interesting part of this service descriptor is that it defines a reference to the context access service. By referring back to the &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;details of dynamically binding (declarative) services&lt;/a&gt;, you can see that this definition will result to the automatic binding of this client to the IContextAccess service, which is provided by the context middleware. Furthermore, the "1..1" cardinality indicates that in order to activate the client, exactly one binding to a single provider of the context access service must be made. When bound (or unboun), a corresponding method is invoked.&lt;br /&gt;&lt;br /&gt;Finally, we are ready to present the code of the Memory Viewer context client:&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial9;&lt;br /&gt;&lt;br /&gt;import org.istmusic.mw.context.IContextAccess;&lt;br /&gt;import org.istmusic.mw.context.exceptions.ContextException;&lt;br /&gt;import org.istmusic.mw.context.events.IContextListener;&lt;br /&gt;import org.istmusic.mw.context.events.ContextChangedEvent;&lt;br /&gt;import org.istmusic.mw.context.ontologies.DefaultMusicOntologyV0_1;&lt;br /&gt;import org.istmusic.mw.context.model.api.IEntity;&lt;br /&gt;import org.istmusic.mw.context.model.api.IScope;&lt;br /&gt;import org.istmusic.mw.context.model.api.IContextElement;&lt;br /&gt;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;import cy.ac.ucy.cs.osgi.tutorial7.memory_model.MemoryContextElement;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public class MemoryViewer implements IContextListener&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;public static final IEntity ENTITY = DefaultMusicOntologyV0_1.ENTITY_DEVICE_THIS;&lt;br /&gt;public static final IScope SCOPE = DefaultMusicOntologyV0_1.SCOPE_RESOURCE_MEMORY;&lt;br /&gt;&lt;br /&gt;private final Logger logger = Logger.getLogger(MemoryViewer.class.getCanonicalName());&lt;br /&gt;&lt;br /&gt;public MemoryViewer()&lt;br /&gt;{&lt;br /&gt;    logger.info("MemoryViewer: constructed");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void contextChanged(ContextChangedEvent event)&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    IContextElement [] contextElements = event.getContextDataset().getContextElements();&lt;br /&gt;    for(int i = 0; i &amp;lt; contextElements.length; i++)&lt;br /&gt;    {&lt;br /&gt;        IContextElement contextElement = contextElements[i];&lt;br /&gt;&lt;br /&gt;        MemoryContextElement memoryContextElement = (MemoryContextElement) contextElement;&lt;br /&gt;        logger.info("ContextViewer: Received -&amp;gt; " + memoryContextElement);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void setContextAccessService(final IContextAccess contextAccess)&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        contextAccess.addContextListener(ENTITY, SCOPE, this);&lt;br /&gt;    }&lt;br /&gt;    catch (ContextException ce)&lt;br /&gt;    {&lt;br /&gt;        logger.throwing(MemoryViewer.class.getName(), "setContextAccessService", ce);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void unsetContextAccessService(final IContextAccess contextAccess)&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        contextAccess.removeContextListener(ENTITY, SCOPE, this);&lt;br /&gt;    }&lt;br /&gt;    catch (ContextException ce)&lt;br /&gt;    {&lt;br /&gt;        logger.throwing(MemoryViewer.class.getName(), "unsetContextAccessService", ce);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The most interesting parts in this class are the handling of the binding (and unbinding) of the context access service (in bold) and the handling of the received events (also in bold). The "setContextAccess" method is used to register &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; context listener for notifications of events related to changes in the memory of this device. Symmetrically to it, the "unsetContextAccess" method is used to unregister from events of the same type.&lt;br /&gt;&lt;br /&gt;At this point, we should note that the context types are defined via the Ontology, which guarantees semantic consistency. For this purpose the &lt;span style="font-style: italic;"&gt;entity&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;scope&lt;/span&gt; are defined by referencing to the appropriate concepts in the ontology, which correspond to the memory resource of this device.&lt;br /&gt;&lt;br /&gt;While registered with the context access service, the memory client receives every notification which corresponds to the registered context type. These notifications are received at the "contextChanged" method (which is defined in the IContextListener interface). In the Memory Viewer client, we simply read each context element received, cast it to the MemoryContextElement type (defined in &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;Tutorial 7&lt;/a&gt;) and then simply print it out on the console. A real, context-aware application would of course the received context data in a more interesting way (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, to adapt its behavior).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Packaging and deploying the Memory Viewer context client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Following a similar approach to when developing OSGi bundles (and context plug-ins), we package the resulting code and the artifact documents (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the Manifest and the service descriptor) in a single JAR file. An example of this JAR file, including a copy of the source code and the "build.xml" ANT configuration file that was used to create it, is available &lt;a href="http://nearchos.googlepages.com/MemoryViewer.jar"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When deployed and started, the memory viewer produces the following output:&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:MemoryViewer.jar&lt;br /&gt;Bundle id is 10&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; refresh 10&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id      State       Bundle&lt;br /&gt;0       ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1       ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2       ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3       ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4       ACTIVE      RunnableProvider_1.0.0&lt;br /&gt;5       ACTIVE      RunnableConsumer_1.0.0&lt;br /&gt;6       ACTIVE      CLI_Client_1.0.0&lt;br /&gt;7       ACTIVE      music-context_0.2.1.0-SNAPSHOT&lt;br /&gt;8       ACTIVE      MemoryModel_1.0.0&lt;br /&gt;9       ACTIVE      MemorySensor_1.0.0&lt;br /&gt;10      RESOLVED    MemoryViewer_1.0.0&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 10&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; Jan 29, 2009 12:34:15 PM cy.ac.ucy.cs.osgi.tutorial9.MemoryViewer &amp;lt;init&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: MemoryViewer: constructed&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jan 29, 2009 12:34:15 PM org.istmusic.mw.context.manager.ContextManager addTrigger&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: Adding trigger for context type&lt;/span&gt;: http://www.ist-music.eu/Ontology_v0_1.xml#concepts.entities.device|this/http://www.ist-music.eu/Ontology_v0_1.xml#concepts.scopes.resources.memory&lt;br /&gt;&lt;br /&gt;Jan 29, 2009 12:34:15 PM cy.ac.ucy.cs.osgi.tutorial8.MemorySensor activate&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: c_activating: Memory plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jan 29, 2009 12:34:16 PM cy.ac.ucy.cs.osgi.tutorial8.MemorySensor run&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: MemorySensor: firing event&lt;/span&gt;: (#concepts.entities.device|this, #concepts.scopes.resources.memory)-&amp;gt;[availableMemory=2437856, memoryLoad=0.5291299940664558]&lt;br /&gt;&lt;br /&gt;Jan 29, 2009 12:34:16 PM cy.ac.ucy.cs.osgi.tutorial9.MemoryViewer contextChanged&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: ContextViewer: Received&lt;/span&gt; -&amp;gt; (#concepts.entities.device|this, #concepts.scopes.resources.memory)-&amp;gt;[availableMemory=2437856, memoryLoad=0.5291299940664558]&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; stop 10&lt;br /&gt;&lt;br /&gt;Jan 29, 2009 12:34:29 PM cy.ac.ucy.cs.osgi.tutorial8.MemorySensor deactivate&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFO: c_deactivating: Memory plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;osgi&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;There are many interesting observations to be made here. First, when the memory viewer (bundle 10) is started, it causes a sequence of events:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;First, the constructor of the memory viewer bundle is invoked.&lt;/li&gt;&lt;li&gt;Second, the context access service is bound, and the memory viewer registers for memory context types, as it is indicated by the &lt;span style="font-style: italic;"&gt;info&lt;/span&gt; log of the context middleware (which adds a trigger for asynchronous notification).&lt;/li&gt;&lt;li&gt;Third, the context middleware realizes that the needed context type is offered by the installed memory context plug-in (bundle 9) and it activates it. This is indicated by memory sensor itself which logs the corresponding action.&lt;/li&gt;&lt;li&gt;Next, the memory context plug-in (bundle 9) starts producing (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, firing) context change events encoding MemoryContextElements. These are communicated to the context middleware.&lt;/li&gt;&lt;li&gt;Finally, the memory viewer (bundle 10) receives the corresponding events and prints out to the console the value of the received MemoryContextElement.&lt;/li&gt;&lt;/ol&gt;Actually, steps 4 and 5 will continue to be triggered automatically, repeatedly producing the corresponding output, until you stop the memory viewer (bundle 10). In particular, as long as the memory context plug-in (bundle 9) is active, it will keep generating events with the predefined interval (5 seconds in this case). As a result, the memory viewer context client will receive a copy of the event from the context middleware and will display it in the output.&lt;br /&gt;&lt;br /&gt;Finally, when you stop the memory viewer (bundle 10), it first unregisters from the context middleware, which in result causes it to deactivate the memory context plugin, returning it to the C_RESOLVED state. More details about the extended plug-in lifecycle were discussed in the &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;previous tutorial&lt;/a&gt; and are also available in [1].&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 9.1&lt;/span&gt;: Develop a context client for the &lt;span style="font-style: italic;"&gt;location&lt;/span&gt; context type and name it LocationViewer. The resulting component must register for &lt;span style="font-style: italic;"&gt;location &lt;/span&gt;context types when active and unregister when not. The received context events must be printed out to the console. You can use the model defined in &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;homework 7.1&lt;/a&gt; and the LocationPlugin defined in &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;homework 8.1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 9.2&lt;/span&gt;: Develop a graphical context client for the &lt;span style="font-style: italic;"&gt;weather &lt;/span&gt;context type and name it WeatherViewer. The resulting component must register for &lt;span style="font-style: italic;"&gt;location &lt;/span&gt;context types when active and unregister when not. The received context events must be displayed in a simple Graphical User Interface (GUI). You can use the model defined in &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;homework 7.1&lt;/a&gt; and the LocationPlugin defined in &lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;homework 8.1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Hint&lt;/span&gt;: Use Java's swing to develop the GUI. In that case, do not forget to include all used packages (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, "javax.swing") into the imported packages definition of the bundle's Manifest. Also make the component visible when it is started and invisible when it is stopped, by implementing the "&lt;span style="font-style: italic;"&gt;activate(ComponentContext)&lt;/span&gt;"&lt;span style="font-style: italic;"&gt; &lt;/span&gt;and "&lt;span style="font-style: italic;"&gt;deactivate(ComponentContext)&lt;/span&gt;" methods, as described in &lt;a href="http://nearchos.blogspot.com/2009/01/component-lifecycle-support-tutorial-5.html"&gt;Tutorial 5&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;[1]. &lt;span style=";font-family:Arial,Courier New;font-size:85%;"  &gt;Nearchos Paspallis, Romain Rouvoy, Paolo Barone, George A. Papadopoulos, Frank Eliassen, Alessandro Mamelli, &lt;a href="http://dx.doi.org/10.1007/978-3-540-88871-0_40"&gt;A Pluggable and Reconfigurable Architecture for a Context-aware Enabling Middleware System&lt;/a&gt;, &lt;i&gt;10th International Symposium on Distributed Objects, Middleware, and Applications (DOA'08)&lt;/i&gt;, Monterrey, Mexico, Nov 10 - 12, 2008, Springer Verlag LNCS 5331, pp. 553-570&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7115678114509726032?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7115678114509726032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7115678114509726032' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7115678114509726032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7115678114509726032'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/developing-context-client-tutorial-9.html' title='Developing a context client - Tutorial 9'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-3658361795190640756</id><published>2009-01-28T16:28:00.008+02:00</published><updated>2009-02-16T09:12:02.209+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='context plug-ins'/><title type='text'>Developing your first context sensor plug-in - Tutorial 8</title><content type='html'>This tutorial builds on the foundations defined in the previous one, which described the use of the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;MUSIC Context Model&lt;/a&gt;, in order to describe the process needed to develop a Context Plug-in. These tutorials are part of a &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series&lt;/a&gt; which aims to first introduce OSGi and declarative services and then the MUSIC Context System.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What are the Context Plug-ins?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Tutorial 6, we introduced the MUSIC Context System architecture and argued that one of its main advantages is the fact that it allows to develop context producers and context consumers independently. Furthermore, as the sources and the sinks are independent, it is possible to reuse the same plug-ins (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, sources) to satisfy the needs of multiple context clients (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, sinks).&lt;br /&gt;&lt;br /&gt;Furthermore, as the plug-ins define their provided (and potentially required) context types in a well-defined, Ontology-backed manner, it is quite possible that the same plug-ins are reused by multiple developers for the construction of various applications and even, sometimes, across various platforms. On the other hand, again as the context clients express their needs in the same well-defined, ontology-backed manner, it is quite possible that the same clients accept context input from various plug-ins, depending on the availability (and resource consumption profile) of the latter.&lt;br /&gt;&lt;br /&gt;Finally, this architecture has the additional benefits of allowing automatic resolution of plug-ins (only those which have no needs for context input or those of which their input is provided are resolved)&lt;br /&gt;A more scientific discussion of the nature of the context plug-ins, along with a description of the intelligent resolution and activation mechanism are described in [1].&lt;br /&gt;&lt;br /&gt;So, the answer to the question of the header, in a few words, is the following: "Context plug-ins are custom OSGi bundles which are designed to produce context data, perhaps by combining lower-level, more elementary context types or simply by wrapping hardware or OS-based sensors."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Anatomy of a Context Plug-in&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As discussed already, Context Plug-ins are first and foremost OSGi bundles. Furthermore, these bundles have the special characteristic that they are discoverable via &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;&lt;span style="font-style: italic;"&gt;Declarative Services&lt;/span&gt;&lt;/a&gt; and they also implement the IContextPlugin interface. Most importantly, this interface specifies two custom life-cycle operations, &lt;span style="font-style: italic;"&gt;activate &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;deactivate&lt;/span&gt;, which are automatically controlled by the middleware.&lt;br /&gt;&lt;br /&gt;In principle a context plug-in, like all other OSGi components adhering to the &lt;span style="font-style: italic;"&gt;Declarative Services &lt;/span&gt;standard, consists of the following parts:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A bundle Manifest descriptor, defining its name, the imported and exported Java packages of the bundle and finally a reference to the service descriptor XML file.&lt;/li&gt;&lt;li&gt;The service descriptor XML file that specifies the service provided by the plug-in (fixed to IContextPlugin) and the properties characterizing the context types &lt;span style="font-style: italic;"&gt;provided&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;required&lt;/span&gt; by the plug-in.&lt;/li&gt;&lt;li&gt;The actual code implementing the Context Plug-in. In its simplest form, this code implements the IContextPlugin interface (possibly by extending one of the abstract implementations available). In practice, the code needs to respond to life-cycle commands as instructed by the middleware with the purpose of starting (and stopping) the generation of context data (encapsulated in context events).&lt;/li&gt;&lt;/ol&gt;This structure is illustrated in the following class diagram:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/MemoryContextPluginClassDiagram.png" title="Structure of the memory context plug-in and utilization of core classes"&gt;&lt;img src="http://nearchos.googlepages.com/MemoryContextPluginClassDiagram.png" alt="Structure of the memory context plug-in and utilization of core classes" border="0" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this class diagram, we illustrate the three parts comprising a typical context plug-in measuring the memory use in the device. Notably, this plug-in extends an &lt;span style="font-style: italic;"&gt;AbstractContextPlugin&lt;/span&gt; class provided by the core context middleware, and which automates a portion of the required functionality. The exact implementation of the memory context plugin are discussed in more detail further on.&lt;br /&gt;&lt;br /&gt;An important detail is the extended life-cycle of the context plug-in components. In particular, while &lt;span style="font-style: italic;"&gt;active&lt;/span&gt; the context plug-ins can transition among three possible states:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;C_INSTALLED&lt;/span&gt;: In this state, the plug-in is simply installed meaning that it has not been resolved. To be resolved, a context plug-in must either have &lt;span style="font-style: italic;"&gt;no &lt;/span&gt;context types required or it must require context types provided by already resolved plug-ins.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;C_RESOLVED&lt;/span&gt;: In this state, the context plug-in has resolved its dependencies and can be started at any time. The only reason for a plug-in to be resolved but not started is when there is no current need for its provided context type, in which case the plug-ins stays inactive to avoid unnecessary resource consumption.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;C_ACTIVE&lt;/span&gt;: This is the third and final possible state for the plug-ins, which indicates that it is resolved and active. In this state, and only in this, the plug-ins are active and generate context events.&lt;/li&gt;&lt;/ul&gt;Notably, these states are triply nested in each other: C_INSTALLED contains C_RESOLVED which itself contains C_ACTIVE. This is also illustrated in the following state diagram:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/ExtendedOSGiComponentLifecycle.png" title="Context Plug-ins: Extended OSGi Component Lifecycle"&gt;&lt;img src="http://nearchos.googlepages.com/ExtendedOSGiComponentLifecycle.png" alt="Context Plug-ins: Extended OSGi Component Lifecycle" border="0" width="640"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;While transitioning &lt;span style="font-style: italic;"&gt;into&lt;/span&gt; (or &lt;span style="font-style: italic;"&gt;out of)&lt;/span&gt; the C_ACTIVE state, the &lt;span style="font-style: italic;"&gt;activate&lt;/span&gt; (or &lt;span style="font-style: italic;"&gt;deactivate&lt;/span&gt;) method of the corresponding plug-in is invoked. To illustrate all these concepts, we here describe the development of a &lt;span style="font-style: italic;"&gt;memory&lt;/span&gt; context plug-in step-by-step.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing the Memory Context Plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Similar to developing a normal OSGi bundle component, the first two steps are to define the Manifest file and the service descriptor. In the case of the &lt;span style="font-style: italic;"&gt;memory&lt;/span&gt; context plug-in, the Manifest is defined as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Memory sensor plug-in for the MUSIC Context System&lt;br /&gt;Bundle-SymbolicName: MemorySensor&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Bundle-ClassPath: .&lt;br /&gt;Import-Package: org.istmusic.mw.context.plugins,&lt;br /&gt;org.istmusic.mw.context.events,&lt;br /&gt;org.istmusic.mw.context.model.api,&lt;br /&gt;org.istmusic.mw.context.model.impl,&lt;br /&gt;org.istmusic.mw.context.util.scheduler,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;cy.ac.ucy.cs.osgi.tutorial7.memory_model&lt;/span&gt;&lt;br /&gt;Service-Component: OSGI-INF/MemorySensor.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, this Manifest is identical to any other OSGi bundle-describing Manifest file. It does not export any packages at all, but it imports a few. Notably, the set of imported packages cannot be typically defined a priori. First, the actual sensor plugin must be coded, and then any packages, beyond the standard ones, which are needed in the code must be added to the "Import-Package" declaration. As you have probably noticed already, this sensor imports the &lt;span style="font-style: italic;"&gt;memory_model&lt;/span&gt; package that was defined in the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;previous tutorial&lt;/a&gt;. The reason for this is that we will leverage that model for encoding the sensed context information. Finally, the Manifest file points to the service descriptor of the plugin (in this case the "MemorySensor.xml"), which is described in the following.&lt;br /&gt;&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="MemorySensor" immediate="true"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial8.MemorySensor"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;service&amp;gt;&lt;br /&gt;   &amp;lt;provide interface="org.istmusic.mw.context.plugins.IContextPlugin"/&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPES" value="memory"/&amp;gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPE_ENTITY[memory]" value="#concepts.entities.device|this"/&amp;gt;&lt;br /&gt;&amp;lt;property name="PROVIDED_CONTEXT_TYPE_SCOPE[memory]" value="#concepts.scopes.resources.memory"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Again, the service descriptor is similar to those used in the development of typical OSGi components, as it was described in the &lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;second tutorial&lt;/a&gt;. The "implementation" element defines the absolute path of the implementing class (which must be a sub-type of IContextPlugin). By default, all context plug-ins must export the IContextPlugin service, which is achieved with the "service" XML element as shown above.  In addition to these however, context plug-ins also define a number of properties. These properties describe the&lt;span style="font-style: italic;"&gt; provided &lt;/span&gt;and the &lt;span style="font-style: italic;"&gt;required&lt;/span&gt; context types of the plug-in. In this example, only provided types are defined but in other cases (i.e., when developing a context reasoner plug-in), required context types can also be defined.&lt;br /&gt;&lt;br /&gt;The format of the properties is as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;PROVIDED_CONTEXT_TYPES&lt;/span&gt;: This property contains a space-separated list of names denoting what context types are provided by the plug-in. For example, a possible assignment could be "p1 p2", where the "p1" and the "p2" types are defined as provided. For each provided type defined in this property, an entity and a scope must also be defined, using the following two parameters.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;PROVIDED_CONTEXT_TYPE_ENTITY[p]&lt;/span&gt;: This property must be defined for each context type "p" that has been specified in the &lt;span style="font-style: italic;"&gt;provided &lt;/span&gt;context types property. The value of this property should be a string corresponding to the actual value of the entity. For example, in the case of the "memory" context type, the entity is the device itself (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, "#concepts.entities.device|this").&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;PROVIDED_CONTEXT_TYPE_SCOPE[p]&lt;/span&gt;: Similar to the entity property, thus one must be defined for each context type "p" that has been specified in the &lt;span style="font-style: italic;"&gt;provided&lt;/span&gt; context types property. The value of this property should be a string corresponding to the actual value of the scope. For example, in the case of the "memory" context type, the scope is the memory resource (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, "#concepts.scopes.resources.memory").&lt;/li&gt;&lt;/ul&gt;It should be noted that besides these three properties, the following three are also possible:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;REQUIRED_CONTEXT_TYPES&lt;/span&gt;: This property contains a space-separated list of names denoting what context types are &lt;span style="font-style: italic;"&gt;required&lt;/span&gt; by the plug-in. For example, a possible assignment could be "r1 r2", where the "r1" and the "r2" types are defined as required ones. For each required context type defined in this property, an entity and a scope must also be defined, using the following two parameters.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;REQUIR&lt;/span&gt;&lt;span style="font-style: italic;"&gt;ED_CONTEXT_TYPE_ENTITY[r]&lt;/span&gt;: This property must be defined for each context type "r" that has been specified in the &lt;span style="font-style: italic;"&gt;required &lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;context types property. The value of this property should be a string corresponding to the actual value of the entity.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;REQUIR&lt;/span&gt;&lt;span style="font-style: italic;"&gt;ED_CONTEXT_TYPE_SCOPE[r]&lt;/span&gt;: Similar to the entity property, thus one must be defined for each context type "r" that has been specified in the &lt;span style="font-style: italic;"&gt;required &lt;/span&gt;context types property. The value of this property should be a string corresponding to the actual value of its scope.&lt;/li&gt;&lt;/ul&gt;Required context types are communicated to the context plug-in automatically (by the middleware), as it will be described later on.&lt;br /&gt;&lt;br /&gt;Finally, to finish with the development of the context plug-in, we define its actual implementation in code. As mentioned already, the implementing class must be a sub-type of IContextPlugin. In this regard, the context plugin can either &lt;span style="font-style: italic;"&gt;implement &lt;/span&gt;the IContextPlugin interface directly, or it can &lt;span style="font-style: italic;"&gt;extend&lt;/span&gt; the AbstractContextPlugin class, as illustrated in the context plugins class diagram. The code of the plugin is listed in the following:&lt;br /&gt;&lt;br /&gt;&lt;pre face="Andale Mono,Lucida Console,Monaco,fixed,monospace" size="12px" style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial8;&lt;br /&gt;&lt;br /&gt;import org.istmusic.mw.context.plugins.AbstractContextPlugin;&lt;br /&gt;import org.istmusic.mw.context.util.scheduler.RecurringEvent;&lt;br /&gt;import org.istmusic.mw.context.util.scheduler.Scheduler;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;import cy.ac.ucy.cs.osgi.tutorial7.memory_model.MemoryContextElement;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;public class &lt;span style="font-weight: bold;"&gt;MemorySensor&lt;/span&gt;&lt;br /&gt;     extends &lt;span style="font-weight: bold;"&gt;AbstractContextPlugin&lt;/span&gt;&lt;br /&gt;      implements Runnable&lt;br /&gt;{&lt;br /&gt; private final Logger logger = Logger.getLogger(MemorySensor.class.getCanonicalName());&lt;br /&gt;&lt;br /&gt; public static final String MEMORY_PLUGIN_ID = "Memory plugin";&lt;br /&gt;&lt;br /&gt; public static final long MIN_WAIT_TIME = 500L; // 0.5 sec&lt;br /&gt;&lt;br /&gt; public static final long INTERVAL = MemoryContextElement.MILLISECONDS_BEFORE_EXPIRY / 2;&lt;br /&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;private final RecurringEvent recurringEvent = new RecurringEvent(this, MIN_WAIT_TIME, INTERVAL);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; private final double totalMemory;&lt;br /&gt;&lt;br /&gt; public MemorySensor()&lt;br /&gt; {&lt;br /&gt;     super(MEMORY_PLUGIN_ID);&lt;br /&gt;&lt;br /&gt;     logger.info("MemorySensor: constructed");&lt;br /&gt;     this.totalMemory = Runtime.getRuntime().totalMemory();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private final Scheduler scheduler = Scheduler.getInstance();&lt;br /&gt;&lt;br /&gt; /** Automatically invoked by the context middleware when the plugin must be activated. */&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void activate()&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     logger.info("c_activating: " + this);&lt;br /&gt;     scheduler.scheduleEvent(recurringEvent);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /** Automatically invoked by the context middleware when the plugin must be deactivated */&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void deactivate()&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     logger.info("c_deactivating: " + this);&lt;br /&gt;     scheduler.removeRecurringEvent(recurringEvent);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void run()&lt;/span&gt;&lt;br /&gt; {&lt;br /&gt;     // acquire memory measurements&lt;br /&gt;     final long availableMemory = Runtime.getRuntime().freeMemory();&lt;br /&gt;     final double memoryLoad = 1d - (availableMemory / totalMemory);&lt;br /&gt;&lt;br /&gt;     // generate memory context element&lt;br /&gt;     MemoryContextElement memoryContextElement&lt;br /&gt;             = new MemoryContextElement(MEMORY_PLUGIN_ID, availableMemory, memoryLoad);&lt;br /&gt;&lt;br /&gt;     // fire context change event&lt;br /&gt;     logger.info("MemorySensor: firing event: " + memoryContextElement);&lt;br /&gt;     fireContextChangedEvent(this, memoryContextElement);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String toString()&lt;br /&gt; {&lt;br /&gt;     // produce a human-readable string&lt;br /&gt;     return MEMORY_PLUGIN_ID;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The first thing to note here is the fact that the class &lt;span style="font-style: italic;"&gt;uses &lt;/span&gt;the "memory_mode package defined in the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;previous tutorial&lt;/a&gt;. The second important observation is that the memory sensor plugin &lt;span style="font-style: italic;"&gt;extends&lt;/span&gt; the AbstractContextPlugin class. With this, we do not need to &lt;span style="font-style: italic;"&gt;implement&lt;/span&gt; each and every method defined in the IContextPlugin interface, but rather simply implement the abstract methods defined in the abstract class and override any methods we need to change the functionality for. This is actually a popular idiom used extensively even in the J2SE libraries themselves (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, in the "javax.swing" package).&lt;br /&gt;&lt;br /&gt;The constructor is quite straight-forward: we simply delegate the call to the super-constructor with the plug-in's ID as argument. Furthermore, in the constructor we initiate the "totalMemory" constant using a core JVM command.&lt;br /&gt;&lt;br /&gt;The interesting part of the plug-in lies in the implementation of the &lt;span style="font-style: italic;"&gt;activate &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;deactivate &lt;/span&gt;methods as well as to the implementation of the &lt;span style="font-style: italic;"&gt;run&lt;/span&gt; method (of the "java.lang.Runnable" interface). The activate (and deactivate) method does a simple thing: it schedules (or unschedules) a recurring event. In this case, we use a custom scheduler which allows for the definition of one-time or recurring events. As shown in this example, the RecurringEvent is constructed by passing it three arguments:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;A class implementing the Runnable interface&lt;/span&gt;: this is the code that will be invoked each time the recurring event is fired. In this case, the MemorySensor class itself is defined to implement the IContextListener interface, so the passed argument is itself (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, "this").&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Minimum wait time&lt;/span&gt;: This long arithmetic value indicates the number of milliseconds the scheduler must wait before it fires an event for the first time. In this example this number is set to 500 (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, half a second).&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Interval&lt;/span&gt;: The interval is also a long arithmetic value indicating the number of milliseconds which the scheduler waits before it repeats an invocation. In this example, the interval is set to 10000 (or 10 seconds) which means that the scheduler will invoke the runnable listener once every 10 seconds).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;When &lt;span style="font-style: italic;"&gt;scheduling&lt;/span&gt; the recurring event with the scheduler ("activate" method), in principle you register for asynchronous invocation of the run method. When you &lt;span style="font-style: italic;"&gt;remove the recurring&lt;/span&gt; event, then you unregister form the asynchronous invocations. This mechanism is quite similar to using Threads, but it uses a Thread pool instead which can be quite beneficial in case you need to deal with resource constrained, mobile devices.&lt;br /&gt;&lt;br /&gt;Finally, we examine the &lt;span style="font-style: italic;"&gt;run&lt;/span&gt; method. This is where the actual context sensing takes place. In the first place, we collect our needed data. In this case we measure the &lt;span style="font-style: italic;"&gt;available memory &lt;/span&gt;using the &lt;span style="font-style: italic;"&gt;freeMemory&lt;/span&gt; core call of Java. Then we compute the &lt;span style="font-style: italic;"&gt;memory load&lt;/span&gt; as a function of the available and total memory.&lt;br /&gt;&lt;br /&gt;In the next step, we construct an instance of the MemoryContextElement (defined in the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;previous tutorial&lt;/a&gt;) by using the sensed data as input.&lt;br /&gt;&lt;br /&gt;Finally, using the generated context element, we fire an event by using the overriden &lt;span style="font-style: italic;"&gt;fireContextChangedEvent&lt;/span&gt; method. The only two arguments are the source (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the plugin itself) and the context element.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Packaging and deploying the Memory Context Plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As usual, we package the code of the plug-in in a JAR file which contains the Manifest, the service descriptor XML file and the Memory Sensor class. A ready JAR file with the source code and an ANT build script is readily available &lt;a href="http://nearchos.googlepages.com/MemorySensor.jar"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To deploy it, follow the steps indicated in the following screen:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:MemorySensor.jar&lt;br /&gt;Bundle id is 9&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 9&lt;br /&gt;file:MemorySensor.jar [9]&lt;br /&gt; Id=9, Status=ACTIVE      Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\9\data&lt;br /&gt; Registered Services&lt;br /&gt;   {org.istmusic.mw.context.plugins.IContextPlugin}={PROVIDED_CONTEXT_TYPE_SCOPE[memory]=#concepts.scopes.resources.memory, component.name=MemorySensor, PROVIDED_CONTEXT_TYPE_ENTITY[memory]=#concepts.entities.device|this, component.id=6, PROVIDED_CONTEXT_TYPES=memory, service.id=31}&lt;br /&gt; No services in use.&lt;br /&gt; No exported packages&lt;br /&gt; Imported packages&lt;br /&gt;   org.istmusic.mw.context.plugins; version="0.0.0"&amp;lt;file:music-context-0.2.1.0-SNAPSHOT.jar [7]&amp;gt;&lt;br /&gt;   org.istmusic.mw.context.util.scheduler; version="0.0.0"&amp;lt;file:music-context-0.2.1.0-SNAPSHOT.jar [7]&amp;gt;&lt;br /&gt;   org.osgi.service.component; version="1.0.0"&amp;lt;file:plugins\org.eclipse.osgi.services_3.1.200.v20071203.jar [3]&amp;gt;&lt;br /&gt;   cy.ac.ucy.cs.osgi.tutorial7.memory_model; version="0.0.0"&amp;lt;file:MemoryModel.jar [8]&amp;gt;&lt;br /&gt; No fragment bundles&lt;br /&gt; Named class space&lt;br /&gt;   MemorySensor; bundle-version="1.0.0"[provided]&lt;br /&gt; No required bundles&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 9&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; Jan 29, 2009 10:05:45 AM cy.ac.ucy.cs.osgi.tutorial8.MemorySensor &amp;lt;init&amp;gt;&lt;br /&gt;INFO: MemorySensor: constructed&lt;br /&gt;Jan 29, 2009 10:05:45 AM org.istmusic.mw.context.manager.ContextManager installPlugin&lt;br /&gt;INFO: CM:Installing: Memory plugin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notably, the bundle exports (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, registers) the IContextPlugin service. Also, when started (i.e., when the plug-in moves in to the ACTIVE state), the middleware detects it and automatically binds to it moving it to the C_INSTALLED state (shown in the extended plugins state diagram shown above). At this point, the plug-in is not started for a simple reason: There is no context listener actively requiring the memory context type, and thus the middleware keeps the plug-in inactive albeit resolved.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing context reasoner plugins&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Besides the AbstractContextPlugin, the developer can also &lt;span style="font-style: italic;"&gt;extend&lt;/span&gt; the AbstractContextReasonerPlugin class. As shown in the context plugin class diagram, the AbstractContextReasonerPlugin class extends the AbstractContextPlugin class. In addition to the facilities provided by the latter, the former also allows for &lt;span style="font-style: italic;"&gt;receiving &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;handling &lt;/span&gt;context events. In this regard, the corresponding plugin must implement the "contextChanged" method (inherited from the IContextListener interface), in which it should listen to events of its required context types (as defined with "REQUIRED_*" properties in the service descriptor) and react based on them. The development of a context reasoner plug-in is the object of the second homework.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 8.1&lt;/span&gt;: Develop a context plug-in to monitor the location. The actual coordinates reported can be simulated (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, fixed or random). You can use the location model developed in homework 7.1 of the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;last tutorial&lt;/a&gt;. You are actually encouraged to do so.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 8.2&lt;/span&gt;: Develop a context reasoner plug-in that will use the location context type (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, as generated from the plug-in of the previous homework) to produce the weather context type. The actual value will be computed as a function of the latitude as follows: "temperature = 5 + (90 - |latitude|) / 1.5". &lt;span style="font-style: italic;"&gt;I.e.&lt;/span&gt;, the temperature is reported as -5&lt;span style="font-family:Arial,Helvetica;"&gt;°&lt;/span&gt;C at the poles and 65&lt;span style="font-family:Arial,Helvetica;"&gt;°C at the equator (which is of course an exaggeration even with the most pessimistic global warming predictions).&lt;/span&gt; The humidity should be constantly reported as 10%. You can use the location and weather models developed in homework 7.1 of the &lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;last tutorial&lt;/a&gt;. You are actually encouraged to do so.&lt;br /&gt;&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;[1]. &lt;span style=";font-family:Arial,Courier New;font-size:85%;"  &gt;Nearchos Paspallis, Romain Rouvoy, Paolo Barone, George A. Papadopoulos, Frank Eliassen, Alessandro Mamelli, &lt;a href="http://dx.doi.org/10.1007/978-3-540-88871-0_40"&gt;A Pluggable and Reconfigurable Architecture for a Context-aware Enabling Middleware System&lt;/a&gt;, &lt;i&gt;10th International Symposium on Distributed Objects, Middleware, and Applications (DOA'08)&lt;/i&gt;, Monterrey, Mexico, Nov 10 - 12, 2008, Springer Verlag LNCS 5331, pp. 553-570&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-3658361795190640756?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/3658361795190640756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=3658361795190640756' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/3658361795190640756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/3658361795190640756'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html' title='Developing your first context sensor plug-in - Tutorial 8'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-1943854785294830819</id><published>2009-01-28T13:00:00.004+02:00</published><updated>2009-02-16T09:15:06.248+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ontology'/><category scheme='http://www.blogger.com/atom/ns#' term='data structures'/><category scheme='http://www.blogger.com/atom/ns#' term='semantics'/><category scheme='http://www.blogger.com/atom/ns#' term='context model'/><title type='text'>The MUSIC Context Model - Tutorial 7</title><content type='html'>In this tutorial, we will cover the context model which supports the MUSIC Context System (introduced in the &lt;a href="http://nearchos.blogspot.com/2009/01/introduction-to-music-context-system.html"&gt;previous tutorial&lt;/a&gt;). For a brief view of the objective of these tutorials, check out the &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;introductory post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The context model is used to enable the following features:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Data encapsulation&lt;/span&gt;: In all programming languages, the developers use specialized data structures, like &lt;a href="http://en.wikipedia.org/wiki/Set_%28computer_science%29"&gt;sets&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Map_%28computer_science%29"&gt;maps&lt;/a&gt;, to implement their software. For the purposes of context-aware applications, we provide a model which is used for encapsulating context data, as it is described in [1] and [2].&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Context semantics&lt;/span&gt;: In order to allow interoperability among individual context providers and context consumers (possibly distributed across different devices), a context model is needed to establish the semantics of each individual context element.&lt;/li&gt;&lt;/ol&gt;In our approach, the context model achieves both these goals by leveraging a three-layered approach as described in [2]. To do so, we employ technology originating from &lt;span style="text-decoration: underline;"&gt;S&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Semantic_web"&gt;emantic Web&lt;/a&gt; research in the form of &lt;a href="http://en.wikipedia.org/wiki/Ontology_%28computer_science%29"&gt;Ontologies&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The MUSIC Context Ontology&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The MUSIC Context System provides an Ontology-backed context dialect which can be used to facilitate interoperability between different devices. This dialect also serves as a common point of reference for developers leveraging third-party context plug-ins for their context-aware applications.&lt;br /&gt;&lt;br /&gt;The MUSIC context dialect is based on two basic terms: Entities and Scopes. The former are used to determine which entity the context type refers to. For instance, is it a person (and who) or a device (and which). The latter are used to identify the scope of the context type. For instance, a context type might refer to the memory resource of a device. While this context dialect is not restricted in any way, we here present the most basic entities and scopes defined in it, to allow for developers to better understand its logic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Entities&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There  are only three entities possible, corresponding to persons (i.e., users), devices and the environment. This is consistent with Dey's definition of context [3]: "&lt;span style="font-style: italic;"&gt;[Context is] any information that can be used to characterize the situation of an entity. An entity is a person, place, or object that is considered relevant to the interaction between a user and an application, including the user and applications themselves&lt;/span&gt;".&lt;br /&gt;&lt;ul&gt;&lt;li&gt;#concepts.entities.user&lt;/li&gt;&lt;li&gt;#concepts.entities.device&lt;/li&gt;&lt;li&gt;#concepts.entities.environment&lt;/li&gt;&lt;/ul&gt;Furthermore, these entities can be combined with a so-called grounding, which further clarifies the entity. In the case of the user, the grounding can be either the special ID "myself", which is automatically dereferenced by the system to the ID of the user who is logged in the system. Alternatively, the grounding can be set directly to the ID of the user in reference. The ID is typically set to the email address of the user.&lt;br /&gt;&lt;br /&gt;For example, when a user with an email address of "nearchos@cs.ucy.ac.cy" is logged in the system, then the following entity:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;#concepts.entities.user|myself&lt;/li&gt;&lt;/ul&gt;is automatically dereferenced to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;#concepts.entities.user|nearchos@cs.ucy.ac.cy&lt;/li&gt;&lt;/ul&gt;The "#concepts.entities.user|myself" is the default user entity value, meaning that it is equivalent to "#concepts.entities.user".&lt;br /&gt;&lt;br /&gt;Additional details and a description of all the groundings possible are available &lt;a href="http://nearchos.googlepages.com/musiccontextontology"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Scopes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The scopes are the basic identifiers of context information. Once the entity to which the context information corresponds to (i.e., by defining it as described above), then the next step is to define the scope of the context information you will provide.&lt;br /&gt;&lt;br /&gt;While there are practically unlimited possibilities on the things you can model with this approach, the default MUSIC Context Ontology defines a limited domain of scopes with the purpose of allowing reuse, interoperability and ease of development. Thus, we here describe these scopes, which can be used to describe mainly basic information about the users, the device resources and the environment.&lt;br /&gt;&lt;br /&gt;One of the most fundamental context scopes is the location, which (as we will see in the following section) can be represented either as absolute coordinates or in the form of a physical address.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;#concepts.scopes.location&lt;/li&gt;&lt;/ul&gt;This scope can be combined with any of the three possible entity types to indicate the location of either a user, a device or the interaction environment.&lt;br /&gt;&lt;br /&gt;Additional details and a more extensive description of the available scope is also provided &lt;a href="http://nearchos.googlepages.com/musiccontextontology"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Representations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The concept of representations is primarily aimed to facilitate &lt;a href="http://en.wikipedia.org/wiki/Model-driven_development"&gt;&lt;span style="font-style: italic;"&gt;Model-Driven Development&lt;/span&gt; (MDD)&lt;/a&gt; by enabling automatic transformation among many possible representations of the same data-structure. For example, a date can be represented both as a string (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, "2009-01-18T10:54:03+02:00") or as a long arithmetic value (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, "1232268843773").&lt;br /&gt;&lt;br /&gt;As this concept is not a critical part of this series of tutorials, I skip further description and point interested readers to &lt;a href="http://nearchos.googlepages.com/musiccontextontology"&gt;this web-page&lt;/a&gt; and to papers [1] and [2].&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Context Model data-structures&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In our context model, we define the following data-structures:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Context elements&lt;/span&gt;: These are the basic structures abstracting context information. For instance, of a developer needs to define a &lt;span style="font-style: italic;"&gt;weather&lt;/span&gt; or a &lt;span style="font-style: italic;"&gt;memory&lt;/span&gt; context type, then a corresponding context element is typically developed to abstract it. Each context element is associated to a  structure, which contains the actual context information in terms of &lt;span style="font-style: italic;"&gt;context values.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Context data&lt;/span&gt;: This data structure is simply used as a container for the actual context values. In this respect, it implements a map which points from a &lt;span style="font-style: italic;"&gt;Scope&lt;/span&gt; to a &lt;span style="font-style: italic;"&gt;Context Value&lt;/span&gt;. For example, if the corresponding context element is of &lt;span style="font-style: italic;"&gt;weather &lt;/span&gt;type, then the contained context values can be of &lt;span style="font-style: italic;"&gt;temperature&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;humidity&lt;/span&gt; types.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Context values&lt;/span&gt;: The context value data-structures are the actual containers of individual context values. For example, a &lt;span style="font-style: italic;"&gt;temperature&lt;/span&gt; context type is a container of the &lt;span style="font-style: italic;"&gt;temperature&lt;/span&gt; value.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Values&lt;/span&gt;: The value structure are elementary data structures such as strings, integers, etc. They are used as containers of context value data. For example, in the case of the &lt;span style="font-style: italic;"&gt;temperature&lt;/span&gt; context value, it is associated to a &lt;span style="font-style: italic;"&gt;float&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;double&lt;/span&gt; value type. Besides elementary context types, &lt;span style="font-style: italic;"&gt;arrays&lt;/span&gt; (of elementary types) are also supported.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Metadata&lt;/span&gt;: The metadata are extra-functional information characterizing &lt;span style="font-style: italic;"&gt;context elements&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;context values&lt;/span&gt; (such as for example a time-stamp indicating the time when the element or value were created). Similar to &lt;span style="font-style: italic;"&gt;context elements&lt;/span&gt;, the &lt;span style="font-style: italic;"&gt;metadata &lt;/span&gt;structures consist of finer-grained &lt;span style="font-style: italic;"&gt;metadatum&lt;/span&gt; value containers.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Metadatum&lt;/span&gt;: Similar to context values, but specialized in encapsulating metadata values only. They also leverage &lt;span style="font-style: italic;"&gt;value &lt;/span&gt;types for encoding the actual data.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The hierarchy of the context model is illustrated in the following &lt;span style="font-style: italic;"&gt;class diagram&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/ContextModelCompact.png" title="The MUSIC Context Model class diagram"&gt;&lt;img src="http://nearchos.googlepages.com/ContextModelCompact.png" alt="The MUSIC Context Model class diagram" border="0" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This figure graphically illustrates the relationship among the basic concepts of the context model. Also, it depicts the three main Ontology-based concepts: Entities, Scopes and Representations. However, to avoid cluttering in the diagram we omit links denoting relationship between the structures and the Ontology concepts. Furthermore, this figure illustrates a number of elementary &lt;span style="font-style: italic;"&gt;Value &lt;/span&gt;implementations (however these are not complete; for example the &lt;span style="font-style: italic;"&gt;arrays&lt;/span&gt; of elementary values are not depicted).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing the Memory Context Model bundle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In order to illustrate the use of the context model, in the following we describe how to develop a bundle providing the model for a simple context type: &lt;span style="font-style: italic;"&gt;memory&lt;/span&gt;. For this purpose, we define a memory context element, enclosing two trivial context values: &lt;span style="font-style: italic;"&gt;available memory&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;memory load&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The development of the memory context model starts with detecting the appropriate entity and scope ontology concepts. In this case, the memory refers to &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; device (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the device in which the sensor is deployed) and the corresponding scope refers to the &lt;span style="font-style: italic;"&gt;memory resource&lt;/span&gt;. In this regard, the entity and the scope are defined as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Entity&lt;/span&gt;: "#concepts.entities.device|this"&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Scope&lt;/span&gt;: "#concepts.scopes.resources.memory"&lt;/li&gt;&lt;/ul&gt;The code of the new &lt;span style="font-style: italic;"&gt;MemoryContextElement&lt;/span&gt; class is illustrated in the following:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial7.memory_model;&lt;br /&gt;&lt;br /&gt;import org.istmusic.mw.context.model.api.*;&lt;br /&gt;import org.istmusic.mw.context.model.impl.Factory;&lt;br /&gt;import org.istmusic.mw.context.ontologies.DefaultMusicOntologyV0_1;&lt;br /&gt;&lt;br /&gt;public class MemoryContextElement implements IContextElement&lt;br /&gt;{&lt;br /&gt;public static final IEntity ENTITY = DefaultMusicOntologyV0_1.ENTITY_DEVICE_THIS;&lt;br /&gt;&lt;br /&gt;public static final IScope SCOPE = DefaultMusicOntologyV0_1.SCOPE_RESOURCE_MEMORY;&lt;br /&gt;&lt;br /&gt;public static final long MILLISECONDS_BEFORE_EXPIRY = 20000L; // 20 seconds&lt;br /&gt;&lt;br /&gt;private final String source;&lt;br /&gt;&lt;br /&gt;private final IMetadata metadata;&lt;br /&gt;&lt;br /&gt;private final MemoryContextData contextData;&lt;br /&gt;&lt;br /&gt;public MemoryContextElement(final String source, final long availableMemory, final double memoryLoad)&lt;br /&gt;{&lt;br /&gt;this.source = source;&lt;br /&gt;this.metadata = Factory.createDefaultMetadata(MILLISECONDS_BEFORE_EXPIRY);&lt;br /&gt;this.contextData = new MemoryContextData(availableMemory, memoryLoad);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IEntity getEntity()&lt;br /&gt;{&lt;br /&gt;return ENTITY;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IScope getScope()&lt;br /&gt;{&lt;br /&gt;return SCOPE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IRepresentation getRepresentation()&lt;br /&gt;{&lt;br /&gt;return null; // ignore for now&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getSource()&lt;br /&gt;{&lt;br /&gt;return source;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IContextData getContextData()&lt;br /&gt;{&lt;br /&gt;return contextData;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IMetadata getMetadata()&lt;br /&gt;{&lt;br /&gt;return metadata;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String toString()&lt;br /&gt;{&lt;br /&gt;return "(" + ENTITY.getEntityTypeAsShortString() + ", "&lt;br /&gt;       + SCOPE.getScopeAsShortString() + ")-&amp;gt;" + contextData;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The code in this example is straight-forward: The memory context element is constructed by specifying its entity and scope (as constants) and by assigning the &lt;span style="font-style: italic;"&gt;memory context data&lt;/span&gt; (see the following paragraph on the &lt;span style="font-style: italic;"&gt;MemoryContextData&lt;/span&gt;) and the &lt;span style="font-style: italic;"&gt;metadata&lt;/span&gt; (as a default implementation abstracting the creation and expiry timestamp).&lt;br /&gt;&lt;br /&gt;The provided &lt;span style="font-style: italic;"&gt;availableMemory&lt;/span&gt; (long) and &lt;span style="font-style: italic;"&gt;memoryLoad&lt;/span&gt; (double) values are passed on for the construction of the &lt;span style="font-style: italic;"&gt;MemoryContextData&lt;/span&gt;. Also, the accessor method for the representation is ignored for now, as we are not tackling inter-representation issues in this series of tutorials.&lt;br /&gt;&lt;br /&gt;In the following, we illustrate the implementation code for the memory context data:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial7.memory_model;&lt;br /&gt;&lt;br /&gt;import org.istmusic.mw.context.model.api.IContextData;&lt;br /&gt;import org.istmusic.mw.context.model.api.IContextValue;&lt;br /&gt;import org.istmusic.mw.context.model.api.IScope;&lt;br /&gt;import org.istmusic.mw.context.model.api.IValue;&lt;br /&gt;&lt;br /&gt;import java.util.Set;&lt;br /&gt;import java.util.HashSet;&lt;br /&gt;&lt;br /&gt;public class MemoryContextData implements IContextData&lt;br /&gt;{&lt;br /&gt;private final AvailableMemoryContextValue availableMemoryContextValue;&lt;br /&gt;&lt;br /&gt;private final MemoryLoadContextValue memoryLoadContextValue;&lt;br /&gt;&lt;br /&gt;public MemoryContextData(final long availableMemory, final double memoryLoad)&lt;br /&gt;{&lt;br /&gt;availableMemoryContextValue = new AvailableMemoryContextValue(availableMemory);&lt;br /&gt;memoryLoadContextValue = new MemoryLoadContextValue(memoryLoad);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IContextValue getContextValue(IScope scopeKey)&lt;br /&gt;{&lt;br /&gt;if(scopeKey == null)&lt;br /&gt;{&lt;br /&gt;    throw new IllegalArgumentException("The scopeKey cannot be null");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if(scopeKey.equals(AvailableMemoryContextValue.SCOPE))&lt;br /&gt;{&lt;br /&gt;    return availableMemoryContextValue;&lt;br /&gt;}&lt;br /&gt;else if(scopeKey.equals(MemoryLoadContextValue.SCOPE))&lt;br /&gt;{&lt;br /&gt;    return memoryLoadContextValue;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public IValue getValue(IScope scopeKey)&lt;br /&gt;{&lt;br /&gt;IContextValue contextValue = getContextValue(scopeKey);&lt;br /&gt;&lt;br /&gt;return contextValue == null ? null : contextValue.getValue();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public Set keySet()&lt;br /&gt;{&lt;br /&gt;final Set keySet = new HashSet();&lt;br /&gt;&lt;br /&gt;keySet.add(AvailableMemoryContextValue.SCOPE);&lt;br /&gt;keySet.add(MemoryLoadContextValue.SCOPE);&lt;br /&gt;&lt;br /&gt;return keySet;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String toString()&lt;br /&gt;{&lt;br /&gt;return "[" + availableMemoryContextValue + ", " + memoryLoadContextValue + "]";&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In this case, the provided arguments are used to initialize the &lt;span style="font-style: italic;"&gt;AvailableMemoryContextValue&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;MemoryLoadContextValue&lt;/span&gt; (both realization of the ContextValue type). The stored values are then accessed via named invocation of the &lt;span style="font-style: italic;"&gt;getContextValue&lt;/span&gt; method where the specified argument indicates the scope of the corresponding value.&lt;br /&gt;&lt;br /&gt;To avoid cluttering, the complete code of the other custom context types is omitted, but is available for examination and reuse in the &lt;a href="http://nearchos.googlepages.com/MemoryModel.jar"&gt;MemoryModel.jar&lt;/a&gt; file., which will be discussed later on.&lt;br /&gt;&lt;br /&gt;The resulting context model, along with its associations to the original model, is illustrated in the following diagram:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/MemoryContextModel.png" title="The extended Memory Context Model class diagram"&gt;&lt;img src="http://nearchos.googlepages.com/MemoryContextModel.png" alt="The extended Memory Context Model class diagram" border="0" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As illustrated in this figure, each custom type corresponds (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, extends) to an equivalent basic model type. The code for the &lt;span style="font-style: italic;"&gt;AvailableMemoryContextValue&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;MemoryLoadContextValue&lt;/span&gt;, although not depicted, is also straight-forward: it provides a reference to the corresponding elementary context type (&lt;span style="font-style: italic;"&gt;LongValue &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;DoubleValue&lt;/span&gt; respectively).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deploying the Memory Context Model bundle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although it provides no actual functionality, here we describe how the context model bundle is dormed and deployed. Its use is limited to exporting the memory context model classes.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Tutorial 7: MemoryModel&lt;br /&gt;Bundle-SymbolicName: MemoryModel&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Import-Package: org.istmusic.mw.context.model.api,&lt;br /&gt;org.istmusic.mw.context.model.impl,&lt;br /&gt;org.istmusic.mw.context.model.impl.values,&lt;br /&gt;org.istmusic.mw.context.ontologies&lt;br /&gt;Export-Package: cy.ac.ucy.cs.osgi.tutorial7.memory_model&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Notably, the Manifest file in this case does not define an XML service descriptor (as we mentioned already, this bundle does not use or provide any services; it is rather used as a library providing (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, exporting) the "cy.ac.ucy.cs.osgi.tutorial7.memory_model" package.&lt;br /&gt;&lt;br /&gt;When deployed, the bundle simply exports the corresponding package, as illustrated in the following console output:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:MemoryModel.jar&lt;br /&gt;Bundle id is 8&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 8&lt;br /&gt;file:MemoryModel.jar [8]&lt;br /&gt;Id=8, Status=INSTALLED   Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\8\data&lt;br /&gt;No registered services.&lt;br /&gt;No services in use.&lt;br /&gt;Exported packages&lt;br /&gt;cy.ac.ucy.cs.osgi.tutorial7.memory_model; version="0.0.0"[exported]&lt;br /&gt;No imported packages&lt;br /&gt;No fragment bundles&lt;br /&gt;No named class spaces&lt;br /&gt;No required bundles&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id      State       Bundle&lt;br /&gt;0       ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1       ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2       ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3       ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4       ACTIVE      RunnableProvider_1.0.0&lt;br /&gt;5       ACTIVE      RunnableConsumer_1.0.0&lt;br /&gt;6       ACTIVE      CLI_Client_1.0.0&lt;br /&gt;7       ACTIVE      music-context_0.2.1.0-SNAPSHOT&lt;br /&gt;8       INSTALLED   MemoryModel_1.0.0&lt;br /&gt;&lt;br /&gt;osgi&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This concludes this tutorial. It is recommended that you try to implement some sample models, as described in the exercises, in order to familiarize yourself with the context model.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Homework 7.1&lt;/span&gt;: Develop a bundle containing the model for a location context type. The created context element should be named &lt;span style="font-style: italic;"&gt;LocationContextElement&lt;/span&gt;. Argue which entity and scope are the most appropriate, based on the discussion presented &lt;a href="http://nearchos.googlepages.com/musiccontextontology"&gt;here&lt;/a&gt;. The context element must refer to a &lt;span style="font-style: italic;"&gt;LocationContextData&lt;/span&gt; structure, containing descriptive information for the &lt;span style="font-style: italic;"&gt;longitude &lt;/span&gt;and the &lt;span style="font-style: italic;"&gt;latitude&lt;/span&gt; (their semantics and value range are described in Wikipedia: &lt;a href="http://en.wikipedia.org/wiki/Longitude"&gt;longitude&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Latitude"&gt;latitude&lt;/a&gt;). The resulting context values should be named &lt;span style="font-style: italic;"&gt;LongitudeContextValue &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;Latitude&lt;/span&gt;&lt;span style="font-style: italic;"&gt;ContextValue&lt;/span&gt;. Both must point to a single &lt;span style="font-style: italic;"&gt;DoubleValue&lt;/span&gt;. The resulting structure must be packaged in a JAR bundle, along with the necessary Manifest file. You must override the "toString" method in the LocationContextElement to generate an easily readable one-line output encoding the location.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 7.2&lt;/span&gt;: Develop a bundle containing the model for a weather context type. The created context element should be named &lt;span style="font-style: italic;"&gt;WeatherContextElement&lt;/span&gt;. Argue which entity and scope are the most appropriate, based on the discussion presented &lt;a href="http://nearchos.googlepages.com/musiccontextontology"&gt;here&lt;/a&gt;. The context element must refer to a &lt;span style="font-style: italic;"&gt;WeatherContextData&lt;/span&gt; structure, containing descriptive information for the &lt;span style="font-style: italic;"&gt;temperature &lt;/span&gt;and the &lt;span style="font-style: italic;"&gt;wind&lt;/span&gt; (described by the direction and the power). The resulting context values should be named &lt;span style="font-style: italic;"&gt;TemperatureContextValue &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;WindContextValue&lt;/span&gt;. The former must point to a single &lt;span style="font-style: italic;"&gt;DoubleValue&lt;/span&gt;, and the latter must point to a &lt;span style="font-style: italic;"&gt;StringValue&lt;/span&gt; and an &lt;span style="font-style: italic;"&gt;IntegerValue&lt;/span&gt; (in the range 1 to 10). The resulting structure must be packaged in a JAR bundle, along with the necessary Manifest file. You must override the "toString" method in the WeatherContextElement to generate an easily readable one-line output encoding the weather.&lt;br /&gt;&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;[1].&lt;span style="font-size:100%;"&gt; &lt;/span&gt;&lt;span style=";font-family:Arial,Courier New;font-size:100%;"  &gt;&lt;span style="font-size:85%;"&gt;Roland Reichle, Michael Wagner, Mohammad Ullah Khan, Kurt Geihs, Massimo Valla, Cristina Fra, Nearchos Paspallis, George A. Papadopoulos, &lt;a href="http://doi.ieeecomputersociety.org/10.1109/PERCOM.2008.29"&gt;A Context Query Language for Pervasive Computing Environments&lt;/a&gt;, &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;5th IEEE Workshop on Context Modeling and Reasoning (CoMoRea) &lt;/span&gt;&lt;span style="font-size:85%;"&gt;in conjunction with the &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;6th IEEE International Conference on Pervasive Computing and Communication (PerCom)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;, Hong Kong, 17–21 March 2008, IEEE Computer Society Press, pp. 434-440&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[2]. &lt;/span&gt;&lt;span style=";font-family:Arial,Courier New;font-size:100%;"  &gt;&lt;span style="font-size:85%;"&gt;Michael Wagner, Roland Reichle, Mohammad Ullah Khan, Kurt Geihs, Jorge Lorenzo, Massimo Valla, Cristina Fra, Nearchos Paspallis, George A. Papadopoulos, &lt;a href="http://dx.doi.org/10.1007/978-3-540-68642-2_23"&gt;A Comprehensive Context Modeling Framework for Pervasive Computing Systems&lt;/a&gt;, &lt;i&gt;8th IFIP International Conference on Distributed Applications and Interoperable Systems (DAIS), 4-6 June, 2008, Oslo, Norway, Springer Verlag LNCS 5053, pp. 281-295&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[3]. &lt;span style="font-size:85%;"&gt;Anind K. Dey, &lt;a href="http://dx.doi.org/10.1007/s007790170019"&gt;&lt;span&gt;Understanding and Using Context&lt;/span&gt;&lt;/a&gt;, &lt;/span&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Personal and Ubiquitous Computing Journal&lt;/span&gt;&lt;span style="font-size:85%;"&gt;, Volume 5 (1), 2001, pp. 4-7&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-1943854785294830819?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/1943854785294830819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=1943854785294830819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1943854785294830819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1943854785294830819'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html' title='The MUSIC Context Model - Tutorial 7'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-1336615093477196228</id><published>2009-01-07T10:44:00.014+02:00</published><updated>2009-01-07T15:20:36.320+02:00</updated><title type='text'>Introduction to the MUSIC Context System - Tutorial 6</title><content type='html'>Continuing in the next section of the "OSGi and MUSIC Context" &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series of tutorials&lt;/a&gt;, we here introduce the basics of the MUSIC Context System. The MUSIC Context System [1] is an OSGi component which provides automated management for multiple, dynamically-available context &lt;span style="font-style: italic;"&gt;providers &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;consumers&lt;/span&gt;. As an OSGi component, the MUSIC Context System exports two services:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IContextAccess&lt;/li&gt;&lt;li&gt;IContextManagement&lt;/li&gt;&lt;/ul&gt;The former provides an API for accessing context information both synchronously and asynchronously. Furthermore, it allows for the use of the &lt;span style="font-style: italic;"&gt;Context Query Language &lt;/span&gt;(CQL) [2]. The latter, provides more advanced access to the internals of the context management component, allowing external components, such as the Distributed Context Management System to function (make context remotely available in this case).&lt;br /&gt;&lt;br /&gt;To install the MUSIC Context System, you first need to build or download the corresponding JAR file. You can build the latest version from source code (using Maven), or you can download a recent version of it from here: "&lt;a href="http://nearchos.googlepages.com/music-context-0.2.1.0-SNAPSHOT.jar"&gt;music-context-0.2.1.0-SNAPSHOT.jar&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;Once you build (or download) and install this JAR file, you can notice a few installed services, as illustrated in the following console output:&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:music-context-0.2.1.0-SNAPSHOT.jar&lt;br /&gt;Bundle id is 7&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 7&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;id      State       Bundle&lt;br /&gt;0       ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1       ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2       ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3       ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4       ACTIVE      RunnableProvider_1.0.0&lt;br /&gt;5       ACTIVE      RunnableConsumer_1.0.0&lt;br /&gt;6       ACTIVE      CLI_Client_1.0.0&lt;br /&gt;7       ACTIVE      music-context_0.2.1.0-SNAPSHOT&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;osgi&amp;gt; services (objectClass=org.istmusic*)&lt;br /&gt;{org.istmusic.mw.context.cache.IContextCacheService}={component.name=context.cache, component.id=5, service.id=28}&lt;br /&gt;Registered by bundle: file:music-context-0.2.1.0-SNAPSHOT.jar [7]&lt;br /&gt;Bundles using service:&lt;br /&gt;file:music-context-0.2.1.0-SNAPSHOT.jar [7]&lt;br /&gt;{org.istmusic.mw.context.cqp.IContextQueryService}={component.name=context.query, component.id=4, service.id=29}&lt;br /&gt;Registered by bundle: file:music-context-0.2.1.0-SNAPSHOT.jar [7]&lt;br /&gt;Bundles using service:&lt;br /&gt;file:music-context-0.2.1.0-SNAPSHOT.jar [7]&lt;br /&gt;{org.istmusic.mw.context.IContextAccess, org.istmusic.mw.context.IContextManagement}={component.name=context.manager, component.id=3, service.id=30}&lt;br /&gt;Registered by bundle: file:music-context-0.2.1.0-SNAPSHOT.jar [7]&lt;br /&gt;No bundles using service.&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;As you can see here, there are three sub-components defined in the context bundle:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Context Cache&lt;/li&gt;&lt;li&gt;Context Query [processor]&lt;/li&gt;&lt;li&gt;Context Manager&lt;/li&gt;&lt;/ul&gt;This architecture is also depicted in the following figure:&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/MUSICContextMiddlewareArchitecture.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 640px; height: 400px;" src="http://nearchos.googlepages.com/MUSICContextMiddlewareArchitecture.PNG" alt="MUSIC Context System - Middleware Architecture" id="BLOGGER_PHOTO_ID_5288489792333395442" border="0" /&gt;&lt;/a&gt;As shown in this figure, the "Context Manager" is the central component, utilizing the services offered by the other two components. For instance, the "Context Cache" component, provides a simple storage service, that is used by both the "Context Manager" and the "Context Query Processor". The latter, offers the CQL service, which is used by the "Context Manager" whenever it needs to handle CQL queries.&lt;br /&gt;&lt;br /&gt;From an client-side point-of-view though, what matters are the two services offered by the "Context Manager" and which were mentioned already. In the following, we show their exact definition and briefly explain what they are used for.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The IContextAccess service&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As mentioned already, the context access service is used for allowing external components, deployed in OSGi, to leverage the capabilities of the context system. The interface (API) of this service is shown in the following listing:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;/**&lt;br /&gt;* This is the main point of interaction with the context service (and the&lt;br /&gt;* context system in general). Any context client requiring to interact&lt;br /&gt;* with the context system can achieve it through this interface.&lt;br /&gt;*/&lt;br /&gt;public interface &lt;span style="font-weight: bold;"&gt;IContextAccess&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;/**&lt;br /&gt; * Provides synchronous access to the specified context data. It returns&lt;br /&gt; * the last context element stored only.&lt;br /&gt; */&lt;br /&gt;public IContextElement &lt;span style="font-weight: bold;"&gt;queryContextLastElement&lt;/span&gt;(IEntity entity, IScope scope)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides synchronous access to the specified context data.&lt;br /&gt; */&lt;br /&gt;public IContextDataset &lt;span style="font-weight: bold;"&gt;queryContext&lt;/span&gt;(IEntity entity, IScope scope)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides asynchronous access to the specified context data.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;queryContext&lt;/span&gt;(IEntity entity, IScope scope, IContextListener listener)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides synchronous access to the context data.&lt;br /&gt; */&lt;br /&gt;public IContextDataset &lt;span style="font-weight: bold;"&gt;queryContext&lt;/span&gt;(final IContextQuery query)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides asynchronous access to the context data. The provided context&lt;br /&gt; * listener is asynchronously contacted once the results of the given&lt;br /&gt; * IContextQuery are available.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;queryContext&lt;/span&gt;(IContextQuery query, IContextListener listener)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides asynchronous access to the context data. By providing a the&lt;br /&gt; * IEntity and the IScope of the required data, the provided&lt;br /&gt; * IContextListener reference is asynchronously notified of context&lt;br /&gt; * changes in the specified entity-scope pair automatically.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;addContextListener&lt;/span&gt;(IEntity entity, IScope scope, IContextListener listener)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides asynchronous access to the context data. This method is used&lt;br /&gt; * along with the #addContextListener(IEntity, IScope, IContextListener) method&lt;br /&gt; * in order to allow unregistering of a context client from a particular&lt;br /&gt; * entity-scope pair.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;removeContextListener&lt;/span&gt;(IEntity entity, IScope scope, IContextListener listener)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides the ability to the context clients to specify which context&lt;br /&gt; * types they require (i.e. because an application was launched, requiring&lt;br /&gt; * additional context types). The identification of a type is done in terms&lt;br /&gt; * of a doublet comprising of an IEntity and a IScope.&lt;br /&gt; *&lt;br /&gt; * When registered as needed, a context type is monitored by the&lt;br /&gt; * context system be means of activating an appropriate context sensor (if&lt;br /&gt; * available). When multiple sensors are available providing the same&lt;br /&gt; * context type, then the system might decide to activate only one or more&lt;br /&gt; * of them, based on the resource availability and the quality of the&lt;br /&gt; * available sensors.&lt;br /&gt; *&lt;br /&gt; * Registering the same (Entity,Scope) doublet twice does not throw an&lt;br /&gt; * exception and does not result in any noticeable change.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;addNeededContextType&lt;/span&gt;(IEntity entity, IScope scope, Object requestor)&lt;br /&gt;        throws ContextException;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Provides the ability to the context clients to specify which context&lt;br /&gt; * types they do not need anymore (i.e. because an application was shut&lt;br /&gt; * down). The identification of a type is done in terms of a doublet&lt;br /&gt; * comprising of an IEntity and a IScope.&lt;br /&gt; *&lt;br /&gt; * Unregistering a non existing (Entity,Scope) doublet does not throw an&lt;br /&gt; * exception and does not result in any noticeable change.&lt;br /&gt; */&lt;br /&gt;public void &lt;span style="font-weight: bold;"&gt;removeNeededContextType&lt;/span&gt;(IEntity entity, IScope scope, Object requestor)&lt;br /&gt;        throws ContextException;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As defined in the comments of the corresponding methods, these methods are used to either explicitly request a specific context type, or register a query (formulated in the CQL language [2]) for processing. As the context system needs to be aware of the &lt;span style="font-style: italic;"&gt;runtime context needs &lt;/span&gt;of the individual applications, it either registers the applications' needs implicitly or it allows for them to express them explicitly (using the last two methods). More details about the functioning of each method can be found in the Javadocs of the "&lt;a href="http://nearchos.googlepages.com/IContextAccess.java"&gt;IContextAccess.java&lt;/a&gt;" interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The IContextManagement service&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unlike context access, the context management service aims for other components which aim at improving or complementing the functionality of the context system. For instance, a component can be used to &lt;span style="font-style: italic;"&gt;distribute &lt;/span&gt;the local context information across a predefined set of nodes. Another example is of a component which connects to the context system in order to access and visualize relevant information.&lt;br /&gt;&lt;br /&gt;In order to enable this kind of functionality, the context management service provides methods which allow to access information about the &lt;span style="font-style: italic;"&gt;needed&lt;/span&gt; and the &lt;span style="font-style: italic;"&gt;provided &lt;/span&gt;context types of the node. The interface of the service is illustrated here:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;/**&lt;br /&gt;* Provides management-level access concerning the internal state of the MUSIC&lt;br /&gt;* context system.&lt;br /&gt;*/&lt;br /&gt;public interface &lt;span style="font-weight: bold;"&gt;IContextManagement&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  /**&lt;br /&gt;   * Returns a set of EntityScopePairs which correspond to the currently&lt;br /&gt;   * required context types.&lt;br /&gt;   */&lt;br /&gt;  public Set &lt;span style="font-weight: bold;"&gt;getCurrentRequiredContextTypes&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Registers for asynchronous notification of when a new required context&lt;br /&gt;   * type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;addRequiredContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Un-registers from asynchronous notification of when a new required&lt;br /&gt;   * context type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;removeRequiredContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Returns a Set of EntityScopePairs which correspond to the currently provided&lt;br /&gt;   * context types.&lt;br /&gt;   */&lt;br /&gt;  public Set &lt;span style="font-weight: bold;"&gt;getCurrentProvidedContextTypes&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Registers for asynchronous notification of when a new provided context&lt;br /&gt;   * type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;addProvidedContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Un-registers from asynchronous notification of when a new provided&lt;br /&gt;   * context type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;removeProvidedContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Returns a set of EntityScopePairs which correspond to the currently&lt;br /&gt;   * required context types from remote sources.&lt;br /&gt;   */&lt;br /&gt;  public Set &lt;span style="font-weight: bold;"&gt;getCurrentRequiredRemoteContextTypes&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Registers for asynchronous notification of when a new required remote&lt;br /&gt;   * context type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;addRequiredRemoteContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Un-registers from asynchronous notification of when a new provided&lt;br /&gt;   * context type (i.e. EntityScopePair) is added or removed.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;removeRequiredRemoteContextTypesListener&lt;/span&gt;(IContextManagementListener listener);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Allows external entities (such as the "Distributed Context Manager") to&lt;br /&gt;   * raise ContextChangedEvents.&lt;br /&gt;   */&lt;br /&gt;  public void &lt;span style="font-weight: bold;"&gt;contextChanged&lt;/span&gt;(ContextChangedEvent event);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The methods of this service allow direct (synchronous) and indirect (asynchronous) access to three context types:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Required Context Types&lt;/span&gt;: Those context types that are &lt;span style="font-style: italic;"&gt;needed&lt;/span&gt; by the currently deployed (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, started) applications&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Provided Context Types&lt;/span&gt;: Those context types that are provided by the currently deployed plug-ins (context sensors and context reasoners)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Required Remote Context Types&lt;/span&gt;: Those context types that are needed locally (by the deployed applications) but which are not offered by any of the locally deployed plug-ins&lt;/li&gt;&lt;/ul&gt;The last method allows for other components (besides the context system and the plug-ins) to generate context events.&lt;br /&gt;&lt;br /&gt;In the following tutorials, we will describe the architecture of the context plug-ins, and how a component-based application can be designed to exploit context information from the context system.&lt;br /&gt;&lt;br /&gt;[1]. &lt;span style=";font-family:Arial,Courier New;font-size:85%;"  &gt;Nearchos Paspallis, Romain Rouvoy, Paolo Barone, George A. Papadopoulos, Frank Eliassen, Alessandro Mamelli, &lt;a href="http://dx.doi.org/10.1007/978-3-540-88871-0_40"&gt;&lt;b&gt;A Pluggable and Reconfigurable Architecture for a Context-aware Enabling Middleware System&lt;/b&gt;&lt;/a&gt;, &lt;i&gt;10th International Symposium on Distributed Objects, Middleware, and Applications (DOA'08)&lt;/i&gt;, Monterrey, Mexico, Nov 10 - 12, 2008, Springer Verlag LNCS 5331, pp. 553-570&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;[2]. &lt;span style=";font-family:Arial,Courier New;font-size:85%;"  &gt;Roland Reichle, Michael Wagner, Mohammad Ullah Khan, Kurt Geihs, Massimo Valla, Cristina Fra, Nearchos Paspallis, George A. Papadopoulos, &lt;a href="http://doi.ieeecomputersociety.org/10.1109/PERCOM.2008.29"&gt;&lt;b&gt;A Context Query Language for Pervasive Computing Environments&lt;/b&gt;&lt;/a&gt;, &lt;i&gt;&lt;i&gt;5th IEEE Workshop on Context Modeling and Reasoning (CoMoRea)&lt;/i&gt; &lt;/i&gt;in conjunction with the &lt;i&gt;&lt;i&gt;6th IEEE International Conference on Pervasive Computing and Communication (PerCom)&lt;/i&gt;&lt;/i&gt;, Hong Kong, 17–21 March 2008, IEEE Computer Society Press, pp. 434-440&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-1336615093477196228?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/1336615093477196228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=1336615093477196228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1336615093477196228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1336615093477196228'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/introduction-to-music-context-system.html' title='Introduction to the MUSIC Context System - Tutorial 6'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7284085151670483726</id><published>2009-01-04T12:15:00.008+02:00</published><updated>2009-01-13T12:41:21.928+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Binding'/><category scheme='http://www.blogger.com/atom/ns#' term='Services'/><title type='text'>Component lifecycle support - Tutorial 5</title><content type='html'>In this part of our &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series of tutorials&lt;/a&gt;, we examine a few details about the component lifecycle support, and also how to update components at runtime.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Component lifecycle support&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When a component is installed, it is first resolved and then started. Resolving a component implies that all its static dependencies (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the imported packages of its bundle container) are resolved (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, exported by some other, installed bundles).&lt;br /&gt;&lt;br /&gt;Furthermore, when using Declarative Services, the dynamic service dependencies of a component must also be resolved in order to be able to start it (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, activate it). We demonstrate these two dependencies in the following example.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Revisiting the CLI Client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this tutorial, we will revise the "CLI_Client" that was developed in the &lt;a href="http://nearchos.blogspot.com/2009/01/interacting-with-cli-tutorial-4.html"&gt;previous tutorial&lt;/a&gt;. In this respect, you can simply copy the code used in the previous example into a new folder and make changes as stated in the following.&lt;br /&gt;&lt;br /&gt;The source code of the new "CLI_Client" class looks as follows:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial5;&lt;br /&gt;&lt;br /&gt;import org.eclipse.osgi.framework.console.CommandProvider;&lt;br /&gt;import org.eclipse.osgi.framework.console.CommandInterpreter;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;import org.osgi.service.component.ComponentContext;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;import java.util.logging.Logger;&lt;br /&gt;&lt;br /&gt;public class CLI_Client implements CommandProvider&lt;br /&gt;{&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  private final Logger logger = Logger.getAnonymousLogger();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;public CLI_Client()&lt;br /&gt;{&lt;br /&gt;  super();&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    logger.info("CLI_Client: Constructed component");&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getHelp()&lt;br /&gt;{&lt;br /&gt;  return "\ttest - Tests interaction with the Runnable service";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  protected void activate(ComponentContext componentContext)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    logger.info("CLI_Client: activate");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  protected void deactivate(ComponentContext componentContext)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    logger.info("CLI_Client: deactivate");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;private Runnable runnableService = null;&lt;br /&gt;&lt;br /&gt;public void setRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;  this.runnableService = runnableService;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void unsetRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;  this.runnableService = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void _test(CommandInterpreter ci)&lt;br /&gt;{&lt;br /&gt;  if(runnableService == null)&lt;br /&gt;  {&lt;br /&gt;    System.out.println("Testing failed: no Runnable service provider available");&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;    System.out.println("Invoking Runnable service ...");&lt;br /&gt;    runnableService.run();&lt;br /&gt;    System.out.println("Done!");&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The changes are marked in bold, and consist of the following additions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Two new packages were imported (org.osgi.service.component.ComponentContext and java.util.logging.Logger)&lt;/li&gt;&lt;li&gt;A logger field was defined, and an &lt;span style="font-style: italic;"&gt;info&lt;/span&gt; log message was added to the constructor&lt;/li&gt;&lt;li&gt;Two methods were defined, with the signature "protected void (de)activate(ComponentContext)"; both of them are simply used to output an &lt;span style="font-style: italic;"&gt;info&lt;/span&gt; log message&lt;/li&gt;&lt;/ul&gt;To make things more interesting, we also make a change in the "CLI_Client.xml" service descriptor, so that the referenced service is not optional, but rather mandatory. This is illustrated in the following code, where the "0..1" value was replaced by "1.1" (be reminded that the first digit signifies optionality and the latter multiplicity):&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="CLI_Client"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial5.CLI_Client"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;service&amp;gt;&lt;br /&gt;&amp;lt;provide interface="org.eclipse.osgi.framework.console.CommandProvider"/&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;reference name="runnable_service"&lt;br /&gt;interface="java.lang.Runnable"&lt;br /&gt;bind="setRunnableService"&lt;br /&gt;unbind="unsetRunnableService"&lt;br /&gt;cardinality="&lt;span style="font-weight: bold;"&gt;1&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;..1&lt;/span&gt;"&lt;br /&gt;policy="dynamic"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next, define the new "MANIFEST.MF" file. Note that the file is exactly the same, except for adding a new, second imported package:&lt;br /&gt;&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Tutorial 5: CLI_Client&lt;br /&gt;Bundle-SymbolicName: CLI_Client&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Import-Package: org.eclipse.osgi.framework.console,&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;org.osgi.service.component&lt;/span&gt;&lt;br /&gt;Service-Component: OSGI-INF/CLI_Client.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Finally, proceed to build the "CLI_Client.jar" JAR file using the same structure as the one used for the original "CLI_Client" (we keep the name of the JAR file the same as the one of the last tutorial on purpose).&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Deploying the new CLI_Client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To deploy the newly developed component, copy the generated JAR file in the deployment folder and replace the one from the previous tutorial. Please note at this point that this has no implications on the running instance of the "CLI_Client" component. To update the actual new component, run the "update" command in the console, as follows:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id      State       Bundle&lt;br /&gt;0       ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1       ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2       ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3       ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4       ACTIVE      RunnableProvider_1.0.0&lt;br /&gt;5       ACTIVE      RunnableConsumer_1.0.0&lt;br /&gt;6       RESOLVED    CLI_Client_1.0.0&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; update 6&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id      State       Bundle&lt;br /&gt;0       ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1       ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2       ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3       ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4       ACTIVE      RunnableProvider_1.0.0&lt;br /&gt;5       ACTIVE      RunnableConsumer_1.0.0&lt;br /&gt;6       INSTALLED   CLI_Client_1.0.0&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;At this point, note how the state of the "CLI_Client" component has changed from "RESOLVED" to "INSTALLED". The "CLI_Client" component can be started again using the "start 6" command.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; start 6&lt;br /&gt;Jan 4, 2009 7:05:14 PM cy.ac.ucy.cs.osgi.tutorial5.CLI_Client &amp;lt;init&amp;gt;&lt;br /&gt;INFO: CLI_Client: Constructed component&lt;br /&gt;Jan 4, 2009 7:05:14 PM cy.ac.ucy.cs.osgi.tutorial5.CLI_Client activate&lt;br /&gt;INFO: CLI_Client: activate&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; stop 4&lt;br /&gt;Jan 4, 2009 7:05:17 PM cy.ac.ucy.cs.osgi.tutorial5.CLI_Client deactivate&lt;br /&gt;INFO: CLI_Client: deactivate&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 4&lt;br /&gt;&lt;br /&gt;Jan 4, 2009 7:05:21 PM cy.ac.ucy.cs.osgi.tutorial5.CLI_Client &amp;lt;init&amp;gt;&lt;br /&gt;INFO: CLI_Client: Constructed component&lt;br /&gt;Jan 4, 2009 7:05:21 PM cy.ac.ucy.cs.osgi.tutorial5.CLI_Client activate&lt;br /&gt;INFO: CLI_Client: activate&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Interestingly, when a component is constructed, activated and deactivated, appropriate log messages appear in the console. This is the result of the OSGi framework constructing the component and invoking the "activate" and "deactivate" methods on it. This is done using a technique commonly referred to as &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_Control"&gt;&lt;span style="font-style: italic;"&gt;Inversion of Control&lt;/span&gt;&lt;/a&gt; (IoC).&lt;br /&gt;&lt;br /&gt;What is even more interesting though, is that stopping and starting a different service (in this case the "RunnableProvider"), causes the component to be stopped and started automatically. This happens because the service descriptor of this updated component defines a mandatory, one-to-one dependency on the "java.lang.Runnable" service. As component with ID #4 starts and stops, the "java.lang.Runnable" service becomes unavailable and back available. Since the "RunnableProvider" is the single only component that offers this service, the Declarative Services runtime realizes that the "CLI_Client" must be deactivated first, and then activated again when the service is available again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 5.1&lt;/span&gt;: Build a second "java.lang.Runnable" provider, and name it "RunnableProvider2" (other than the name, it can be identical to the original "RunnableProvider"). Then deploy and start it. While both the "RunnableProvider" and the "RunnableProvider2" are both started, along with the new "CLI_Client", try to stop the used provider and note what happens to the "CLI_Client".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 5.2&lt;/span&gt;: Discuss with a few words each possible transition in the OSGi bundle's lifecycle state diagram (from &lt;a href="http://www.osgi.org/Download/File?url=/download/r4v41/r4.core.pdf"&gt;OSGi Service Platform Release 4 Version 4.1 Core Specification&lt;/a&gt;):&lt;br /&gt;&lt;a href="http://nearchos.googlepages.com/OSGicomponentlifecycle.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 480px; height: 333px;" src="http://nearchos.googlepages.com/OSGicomponentlifecycle.png" alt="OSGi component lifecycle" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 5.1&lt;/span&gt;: Read section 2.9 (Incremental Development) in the second chapter of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;Neil Bartlett's book&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7284085151670483726?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7284085151670483726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7284085151670483726' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7284085151670483726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7284085151670483726'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/component-lifecycle-support-tutorial-5.html' title='Component lifecycle support - Tutorial 5'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-6416595439344318262</id><published>2009-01-03T13:32:00.007+02:00</published><updated>2009-01-13T12:42:04.468+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='Command-Line Interface (CLI)'/><category scheme='http://www.blogger.com/atom/ns#' term='Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Binding'/><category scheme='http://www.blogger.com/atom/ns#' term='Services'/><title type='text'>Interacting with the CLI - Tutorial 4</title><content type='html'>In the next post of this &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series of tutorials&lt;/a&gt;, we describe a way to interact with the &lt;a href="http://en.wikipedia.org/wiki/Command_line_interface"&gt;&lt;span style="font-style: italic;"&gt;Command Line Interface&lt;/span&gt;&lt;/a&gt; (CLI) of the Equinox OSGi console. Taking advantage of this functionality, we then illustrate the power of Declarative Services by demonstrating how dynamic binding is handled by the components.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Developing the CLI Client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this example, we leverage a mechanism provided by OSGi which allows interacting with the framework via commands at the console at runtime. To achieve this, we use OSGi's CommandProvider mechanism. The latter, is implemented as a &lt;span style="font-style: italic;"&gt;service&lt;/span&gt; which is exported by a component that wishes to interact with the framework via CLI, and which is consumed by the framework itself.&lt;br /&gt;&lt;br /&gt;The bundle structure is similar to the one used in the previous two tutorials, and is omitted for brevity. The service descriptor on the other hand, has the distinctive that it both provides a service (the "CommandProvider") and it references one (the "java.lang.Runnable"):&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="CLI_Client"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial4.CLI_Client"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;service&amp;gt;&lt;br /&gt;&amp;lt;provide interface="org.eclipse.osgi.framework.console.CommandProvider"/&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;reference name="runnable_service"&lt;br /&gt;   interface="java.lang.Runnable"&lt;br /&gt;   bind="setRunnableService"&lt;br /&gt;   unbind="unsetRunnableService"&lt;br /&gt;   cardinality="0..1"&lt;br /&gt;   policy="dynamic"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;It is worth noting that the &lt;span style="font-style: italic;"&gt;reference&lt;/span&gt; element in this XML descriptor is identical to the one used in the "ServiceConsumer" described in the &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;previous tutorial&lt;/a&gt;. On the other hand, the implementation class is of course adjusted to the new class, and a &lt;span style="font-style: italic;"&gt;service&lt;/span&gt; element is added to define that this component implements the "CommandProvider" service, and thus is capable of interacting the CLI in the console.&lt;br /&gt;&lt;br /&gt;Proceeding to the source code of the CLI_Client component, again you can observe some similarities to the code of the "RunnableConsumer", &lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the default constructor and the standard setter methods for the "java.lang.Runnable" service :&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial4;&lt;br /&gt;&lt;br /&gt;import org.eclipse.osgi.framework.console.CommandProvider;&lt;br /&gt;import org.eclipse.osgi.framework.console.CommandInterpreter;&lt;br /&gt;&lt;br /&gt;public class CLI_Client implements CommandProvider&lt;br /&gt;{&lt;br /&gt;public CLI_Client()&lt;br /&gt;{&lt;br /&gt;super();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getHelp()&lt;br /&gt;{&lt;br /&gt;return "\ttest - Tests interaction with the Runnable service";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private Runnable runnableService = null;&lt;br /&gt;&lt;br /&gt;public void setRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;this.runnableService = runnableService;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void unsetRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;this.runnableService = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void _test(CommandInterpreter ci)&lt;br /&gt;{&lt;br /&gt;if(runnableService == null)&lt;br /&gt;{&lt;br /&gt;  System.out.println("Testing failed: no Runnable service provider available");&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;  System.out.println("Invoking Runnable service ...");&lt;br /&gt;  runnableService.run();&lt;br /&gt;  System.out.println("Done!");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The most important observation in this code is that the implementing class in not a &lt;a href="http://en.wikipedia.org/wiki/POJO"&gt;POJO&lt;/a&gt; anymore (compared to the previous two tutorials). Rather, the class &lt;span style="font-style: italic;"&gt;implements&lt;/span&gt; the "CommandProvider" interface and even imports two classes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;org.eclipse.osgi.framework.console.CommandProvider&lt;/li&gt;&lt;li&gt;org.eclipse.osgi.framework.console.CommandInterpreter&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Furthermore, a method with the signature "getHelp()" is defined, in order to implement the "CommandProvider" interface. Finally, the class defines a method with the signature "_test(CommandInterpreter)", which is its custom way of interacting with the console (the preceding underscore is a required character for a new command).&lt;br /&gt;&lt;br /&gt;Finally, the bundle's MANIFEST is similar to those defined in the previous tutorials, but it introduces the new "Import-Package" parameter type:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Tutorial 4: CLI_Client&lt;br /&gt;Bundle-SymbolicName: CLI_Client&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Import-Package: org.eclipse.osgi.framework.console&lt;br /&gt;Service-Component: OSGI-INF/CLI_Client.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This new parameter type specifies packages that this bundle needs. A similar parameter type, namely "Export-Package", defines packages that are exported by the bundle. At runtime, OSGi evaluates the needs of each bundle against the offered packages, and it resolves only those bundles of which their needed packages  are offered by some other, installed bundles. This, in principle, provides a powerful encapsulation mechanism (cf. &lt;a style="font-style: italic;" href="http://en.wikipedia.org/wiki/Information_hiding"&gt;information hiding&lt;/a&gt;), which improves that of plain Java.&lt;br /&gt;&lt;br /&gt;Overall, with the new additions we achieve to introduce new functionality to the CLI Client (compared to the "RunnableProvider" of the &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;previous tutorial&lt;/a&gt;), in terms of the "test" method that can be invoked in the console. We illustrate this new functionality by deploying, starting and testing the CLI Client.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deploying and activating the CLI_Client&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First, make sure that you have followed the steps described in the previous tutorials to install and activate the "RunnableProvider" and the "RunnableConsumer" (if some components are not started, start them with the "start ID#" command).&lt;br /&gt;&lt;br /&gt;Then, proceed to install and activate the CLI_Client. Providing the "bundle 6" command (where 6 is the ID assigned to the CLI Client by the framework), we observe that the component registers the "CommandProvider" service (which is used by the framework for &lt;span style="font-style: italic;"&gt;Command Line Interaction&lt;/span&gt; as described already) and it uses the "java.lang.Runnable" service, provided by the "RunnableProvider". Furthermore, we note that the bundle &lt;span style="font-style: italic;"&gt;imports&lt;/span&gt; a package related to OSGi.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:CLI_Client.jar&lt;br /&gt;Bundle id is 6&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 6&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 6&lt;br /&gt;file:CLI_Client.jar [6]&lt;br /&gt;Id=6, Status=ACTIVE      Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\6\data&lt;br /&gt;Registered Services&lt;br /&gt;{org.eclipse.osgi.framework.console.CommandProvider}={component.name=CLI_Client, component.id=10, service.id=30}&lt;br /&gt;Services in use:&lt;br /&gt;{java.lang.Runnable}={component.name=RunnableProvider, component.id=9, service.id=29}&lt;br /&gt;No exported packages&lt;br /&gt;Imported packages&lt;br /&gt;org.eclipse.osgi.framework.console; version="1.0.0"&amp;lt;System Bundle [0]&amp;gt;&lt;br /&gt;No fragment bundles&lt;br /&gt;Named class space&lt;br /&gt;CLI_Client; bundle-version="1.0.0"[provided]&lt;br /&gt;No required bundles&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; test&lt;br /&gt;Invoking Runnable service ...&lt;br /&gt;RunnableProvider says hi!&lt;br /&gt;Done!&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; stop 4&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; test&lt;br /&gt;Testing failed: no Runnable service provider available&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Notably, when we invoke the custom "test" command, the framework invokes the corresponding method in the "CLI_Client" component, which prints out a message ("Invoking Runnable service ..."), then invokes the service (which results to the output of "RunnableProvider says hi!", as it was specified in the &lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;second tutorial&lt;/a&gt;) and finally it prints out a third line ("Done!").&lt;br /&gt;&lt;br /&gt;This means that the invocation of the service was successful, and resulted to the invocation of the "run()" method all the way from the client side, to the service side. Just to make sure that the dynamic binding works, we can try to stop the "ServiceProvider" and run the "test" command again. The former causes the unbinding of the "java.lang.Runnable" service from the clients, which results to setting it to &lt;span style="font-style: italic;"&gt;null&lt;/span&gt; and thus the print-out of the "Testing failed: no Runnable service provider available" message.&lt;br /&gt;&lt;br /&gt;Finally, to show how a service provider can serve more than one clients simultaneously, we can try starting the service back again (via the "start 4" command), and then inspect the service:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; start 4&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; services (objectClass=java.lang*)&lt;br /&gt;{java.lang.Runnable}={component.name=RunnableProvider, component.id=12, service.id=32}&lt;br /&gt;Registered by bundle: file:RunnableProvider.jar [4]&lt;br /&gt;Bundles using service:&lt;br /&gt;file:RunnableConsumer.jar [5]&lt;br /&gt;file:CLI_Client.jar [6]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In this case, we can observe that the service is registered by the "RunnableProvider" component, and is assigned an ID (32 in this case, might be different in your case). Notably, there are two bundles using the service: the "RunnableConsumer" defined in the &lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;previous tutorial&lt;/a&gt; and the "CLI_Client" defined in this one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 4.1&lt;/span&gt;: Read section 2.10 (Interacting with the Framework) in the second chapter of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;Neil Bartlett's book&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 4.2&lt;/span&gt;: Write a bundle that periodically checks the contents of a directory in the filesystem. Whenever a new file with the extension ".jar" appears in that directory, print out an appropriate message.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-6416595439344318262?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/6416595439344318262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=6416595439344318262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6416595439344318262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6416595439344318262'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/interacting-with-cli-tutorial-4.html' title='Interacting with the CLI - Tutorial 4'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-1982578001078298569</id><published>2009-01-02T12:32:00.011+02:00</published><updated>2009-02-12T12:04:41.699+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Binding'/><category scheme='http://www.blogger.com/atom/ns#' term='Services'/><title type='text'>Binding declarative services - Tutorial 3</title><content type='html'>This is the next entry in this &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;series of tutorials&lt;/a&gt;, where we will show how a simple component can be bound to a service. In the &lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;first tutorial&lt;/a&gt;, we learned how to install and start the Equinox OSGi framework and in the &lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;second one&lt;/a&gt;, we learned how to construct a simple component declaring an offered service.&lt;br /&gt;&lt;br /&gt;Assuming you have followed all the steps described in the first two tutorials, then your OSGi runtime should have four components installed and started, as illustrated in the following screen:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1 ACTIVE org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2 ACTIVE org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3 ACTIVE org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4 ACTIVE RunnableProvider_1.0.0&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Developing the client side of the &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Runnable&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; service&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this part, we describe how to develop a component that can be automatically bound to the &lt;span style="font-style: italic;"&gt;java.lang.Runnable&lt;/span&gt; service, exported by the Runnable Provider component. We will name this component "RunnableConsumer".&lt;br /&gt;&lt;br /&gt;The bundle structure is quite similar to the one of the "RunnableProvider", described in the &lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;second tutorial&lt;/a&gt;:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;+- META-INF&lt;br /&gt;|  +- MANIFEST.MF&lt;br /&gt;|&lt;br /&gt;+- OSGI-INF&lt;br /&gt;|  +- RunnableConsumer.xml&lt;br /&gt;|&lt;br /&gt;+- cy&lt;br /&gt;+- ac&lt;br /&gt;+- ucy&lt;br /&gt;+- cs&lt;br /&gt;+- osgi&lt;br /&gt;  +- tutorial3&lt;br /&gt;     +- RunnableConsumer.class&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The MANIFEST file is also quite similar to the one defined for the "RunnableProvider":&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Tutorial 3: Runnable consumer&lt;br /&gt;Bundle-SymbolicName: RunnableConsumer&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Service-Component: OSGI-INF/RunnableConsumer.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The main differences of the client side from the service provider are in the Java source code implementing the component, and in the service descriptor. As opposed to the "RunnableProvider", the "RunnableConsumer" does not define a provided service, but rather just a &lt;span style="font-style: italic;"&gt;reference&lt;/span&gt; to a needed service, as follows:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;component name="RunnableConsumer"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial3.RunnableConsumer"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;reference name="runnable_service"&lt;br /&gt;   interface="java.lang.Runnable"&lt;br /&gt;   bind="setRunnableService"&lt;br /&gt;   unbind="unsetRunnableService"&lt;br /&gt;   cardinality="0..1"&lt;br /&gt;   policy="dynamic"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The "reference" element in the service descriptor specifies that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The component has a binding to a service, and the name of the binding is set to "runnable_service"&lt;/li&gt;&lt;li&gt;The needed service is one which implements the "java.lang.Runnable" interface&lt;/li&gt;&lt;li&gt;To bind this component with a provider of the service, the framework must invoke the "setRunnableService" method&lt;/li&gt;&lt;li&gt;Similarly, to unbind the component from a provider, the framework must invoke the "undetRunnableService" method&lt;/li&gt;&lt;li&gt;The cardinality parameter has the form "x..y", where x can be either '0' or '1' and y can be either '1' or 'n'. The first parameter specifies &lt;span style="font-style: italic;"&gt;optionality&lt;/span&gt;, and the second one specifies &lt;span style="font-style: italic;"&gt;multiplicity&lt;/span&gt;. For instance, x='0' means that a binding to the service is &lt;span style="font-style: italic;"&gt;optional&lt;/span&gt;, while x='1' means that the binding is  (otherwise the component can not be resolved and activated). On the other hand, y='1' implies single binding only, where the component can only be bound to &lt;span style="font-style: italic;"&gt;just one&lt;/span&gt; service provider at a time, while y='n' implies that multiple service providers can be bound to the component simultaneously.&lt;/li&gt;&lt;li&gt;The last parameter, &lt;span style="font-style: italic;"&gt;policy&lt;/span&gt;, can be set to either "dynamic" or "static". This controls the binding to new service providers at runtime. When the value is set to "static", then it is implied that the component cannot handle dynamic switching of service providers and thus the framework constructs a new instance of the component when the service provider changes. On the other hand, when the policy is set to "dynamic", then the binding and unbinding of service providers takes place dynamically on the same component instance. As the former is more heavy-weight, it is recommended that the components are designed and implemented so that they support the dynamic policy. The default value is "static", which means that unless you specify the policy parameter as "dynamic", it is going to be set as "static".&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Next, we show the class source code, which is quite straightforward:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial3;&lt;br /&gt;&lt;br /&gt;public class RunnableConsumer&lt;br /&gt;{&lt;br /&gt;private Runnable runnableService = null;&lt;br /&gt;&lt;br /&gt;public void setRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;this.runnableService = runnableService;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void unsetRunnableService(Runnable runnableService)&lt;br /&gt;{&lt;br /&gt;this.runnableService = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public RunnableConsumer()&lt;br /&gt;{&lt;br /&gt;super();&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This class is also a &lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/POJO"&gt;POJO object&lt;/a&gt;, just like the Service Provider. It specifies a reference to a "java.lang.Runnable" type of service, along with straightfoward setter methods (complying to the signatures defined in the service descriptor). Evidently, this code is not too fascinating, but combined with the service descriptor it reveals the power of OSGi and Declarative Services.&lt;br /&gt;&lt;br /&gt;The last step is to put everything together and construct the JAR file of the bundle. Similar to the "RunnableProvider", we construct the "RunnableConsumer" by compiling the Java class and adding the metadata as defined in the bundle structure. The source code, the metadata and an optional ANT build script are included in the &lt;a href="http://nearchos.googlepages.com/RunnableConsumer.jar"&gt;RunnableConsumer&lt;/a&gt; JAR file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deployment and activation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We first install the newly constructed component using the, now familiar, "install" command of the console:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:RunnableConsumer.jar&lt;br /&gt;Bundle id is 5&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 5&lt;br /&gt;file:RunnableConsumer.jar [5]&lt;br /&gt;Id=5, Status=INSTALLED   Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\5\data&lt;br /&gt;No registered services.&lt;br /&gt;No services in use.&lt;br /&gt;No exported packages&lt;br /&gt;No imported packages&lt;br /&gt;No fragment bundles&lt;br /&gt;No named class spaces&lt;br /&gt;No required bundles&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As shown in this listing, at the time the component is simply installed, assigned the ID #5, and has no services in use. As soon as we start the service, using the "start 5" command, the component is bound to the "java.lang.Runnable" service provided by the "RunnableProvider" component, as shown here:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; start 5&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 5&lt;br /&gt;file:RunnableConsumer.jar [5]&lt;br /&gt;Id=5, Status=ACTIVE      Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\5\data&lt;br /&gt;No registered services.&lt;br /&gt;Services in use:&lt;br /&gt;{java.lang.Runnable}={component.name=RunnableProvider, component.id=0, service.id=26}&lt;br /&gt;No exported packages&lt;br /&gt;No imported packages&lt;br /&gt;No fragment bundles&lt;br /&gt;Named class space&lt;br /&gt;RunnableConsumer; bundle-version="1.0.0"[provided]&lt;br /&gt;No required bundles&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Later on, if we stop the "ServiceProvider" bundle, then the component is unbound from the service, although its instance is still around, deployed in the framework and awaiting for a new service provider:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; stop 4&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; bundle 5&lt;br /&gt;file:RunnableConsumer.jar [5]&lt;br /&gt;Id=5, Status=ACTIVE      Data Root=C:\eclipse\configuration\org.eclipse.osgi\bundles\5\data&lt;br /&gt;No registered services.&lt;br /&gt;No services in use.&lt;br /&gt;No exported packages&lt;br /&gt;No imported packages&lt;br /&gt;No fragment bundles&lt;br /&gt;Named class space&lt;br /&gt;RunnableConsumer; bundle-version="1.0.0"[provided]&lt;br /&gt;No required bundles&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In the next tutorial, we will develop a more powerful client for the "java.lang.Runnable" service, featuring user-interaction via the command-line.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 3.1&lt;/span&gt;: Read the third chapter (Introduction to Services) of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;Neil Bartlett's book&lt;/a&gt;. You can read just the first four sections for now, &lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, 4.1, 4.2, 4.3 and 4.4.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-1982578001078298569?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/1982578001078298569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=1982578001078298569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1982578001078298569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1982578001078298569'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html' title='Binding declarative services - Tutorial 3'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-8427618319490714757</id><published>2009-01-01T11:51:00.011+02:00</published><updated>2009-02-03T15:00:47.288+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Services'/><title type='text'>Your first component - Tutorial 2</title><content type='html'>In the &lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;previous tutorial&lt;/a&gt;, we introduced OSGi and showed how you can download, install and start the Equinox framework, and prepared it for using Declarative Services.  In this tutorial, we will see how your first component can be implemented.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The bundle structure&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As already mentioned in the &lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;first tutorial&lt;/a&gt;, bundles are packaged in JAR files. Inside a JAR, the files are organized with the following structure:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;+- META-INF&lt;br /&gt;|  +- MANIFEST.MF&lt;br /&gt;|&lt;br /&gt;+- OSGI-INF&lt;br /&gt;|  +- RunnableProvider.xml&lt;br /&gt;|&lt;br /&gt;+- cy&lt;br /&gt;+- ac&lt;br /&gt;+- ucy&lt;br /&gt; +- cs&lt;br /&gt;    +- osgi&lt;br /&gt;       +- tutorial2&lt;br /&gt;          +- RunnableProvider.class&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This structure contains the Java classes (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, in the "cy.ac.ucy.cs.osgi.tutorial.*" package structure) along with the configuration data of the bundle (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, "META_INF/MANIFEST.MF") and of the component (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, "OSGI-INF/RunnableProvider.xml"). We will study these parts one by one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The implementation code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this tutorial, we develop a very simple component, offering a very simple service. The source code for the implementing class looks as follows:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;package cy.ac.ucy.cs.osgi.tutorial2;&lt;br /&gt;&lt;br /&gt;public class RunnableProvider implements Runnable&lt;br /&gt;{&lt;br /&gt;public void run()&lt;br /&gt;{&lt;br /&gt;System.out.println("RunnableProvider says hi!");&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This simple class implements the "java.lang.Runnable" interface, which specifies a single method: "public void run()". In this example we provide the most simple (and useless) implementation, just to illustrate how Declarative Services work. When the service is invoked, a message is printed in the console where the "RunnableProvider" is deployed.&lt;br /&gt;&lt;br /&gt;It is worth noting that this class is a Plain Old Java Object (POJO), and thus requires no additional libraries for compiling it. But, in order to become OSGi deployable, and Declarative Services recognizable, this component must be accompanied with the appropriate metadata.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The service descriptor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As a Declarative Services component, the RunnableProvider must be accompanied by an appropriate service descriptor, as the one illustrated in the following:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;component name="RunnableProvider"&amp;gt;&lt;strike&gt;&amp;lt;/component&amp;gt;&lt;/strike&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;implementation class="cy.ac.ucy.cs.osgi.tutorial2.RunnableProvider"/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;service&amp;gt;&lt;br /&gt;&amp;lt;provide interface="java.lang.Runnable"/&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/component&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This file, which we named "RunnableDescriptor.xml" in this example, is expressed in XML and is used to specify the defined component, along with any provided (and as we will later on, required) services.&lt;br /&gt;&lt;br /&gt;In this case, the component is named "RunnableProvider" and its implementation is provided by the class we specified already: "cy.ac.ucy.cs.osgi.tutorial2.RunnableProvider". Furthermore, this component provides a service, as it is specified by the "java.lang.Runnable" interface.&lt;br /&gt;&lt;br /&gt;In &lt;span style="font-style: italic;"&gt;real&lt;/span&gt; applications, the provided services correspond to more complex, custom interfaces. However, in this case we chose an interface which is standard in the &lt;a href="http://en.wikipedia.org/wiki/Java_Virtual_Machine"&gt;JRE&lt;/a&gt;, so that we do not have to export/import any classes at this point (this will be presented in another tutorial).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The bundle manifest&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Finally, the last piece that is needed to make the bundle deployable is the bundle manifest. This file describes the library dependencies of the bundle (imported and exported packages), the name and version of the bundle and a reference to the service descriptor.&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;Manifest-Version: 1.0&lt;br /&gt;Bundle-ManifestVersion: 2&lt;br /&gt;Bundle-Name: Tutorial 2: Runnable provider&lt;br /&gt;Bundle-SymbolicName: RunnableProvider&lt;br /&gt;Bundle-Version: 1.0.0&lt;br /&gt;Service-Component: OSGI-INF/RunnableProvider.xml&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;(&lt;span style="font-weight: bold;"&gt;Important&lt;/span&gt;: Please make sure that you add an empty line at the end of every MANIFEST file you define, because otherwise you risk that the parser will truncate the last line of your file.)&lt;br /&gt;&lt;br /&gt;Most of the properties in this bundle descriptor are self-explanatory. The last parameter points to the corresponding service descriptor, inside the JAR package. Finally, in this example, there are no imported or exported packages.&lt;br /&gt;&lt;br /&gt;To produce the required file, simply compile the Java class and package everything together in a JAR file with the structure described above. A version of such a JAR file is available &lt;a href="http://nearchos.googlepages.com/RunnableProvider.jar"&gt;here&lt;/a&gt;. It is also possible to automate building such bundles using ANT or MAVEN. An example ANT build script is included in the &lt;a href="http://nearchos.googlepages.com/RunnableProvider.jar"&gt;RunnableProvider&lt;/a&gt; JAR file. Furthermore, the same JAR file includes a copy of the RunnableProvider's Java source code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deploying and starting your first component&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you have produced the JAR-packaged bundle, the next step is to deploy it. Following the same approach as the one described in the first tutorial, you can install and start the RunnableProvider bundle:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:RunnableProvider.jar&lt;br /&gt;Bundle id is 4&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 4&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1 ACTIVE org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2 ACTIVE org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3 ACTIVE org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;4 ACTIVE RunnableProvider_1.0.0&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; services (objectClass=java.lang*)&lt;br /&gt;{java.lang.Runnable}={component.name=RunnableProvider, component.id=0, service.id=26}&lt;br /&gt;Registered by bundle: file:RunnableProvider.jar [4]&lt;br /&gt;No bundles using service.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The "services" command results to the system displaying all services registered by any components. As those services might be numerous though, we use a filtering option ("services (objectClass=java.lang*)". This filter blocks any services that do not start with a "java.lang" package prefix.&lt;br /&gt;&lt;br /&gt;For testing purposes, you can then stop the RunnableProvider bundle and issue the same "services" command a second time. You will then realize that the "java.lang.Runnable" service is not offered anymore.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 2.1&lt;/span&gt;: After you deploy and start your component, as explained in this tutorial, test again the commands that you have investigated in Homework 1.1 (&lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;Tutorial 1&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 2.2&lt;/span&gt;: Read the second chapter (First Steps in OSGi) of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;Neil Bartlett's book&lt;/a&gt;. You can skip sections 2.2, 2.3, 2.4, 2.5 and 2.6. You can also skip sections 2.9 and 2.10 for now (they will be covered in follow-up tutorials).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-8427618319490714757?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/8427618319490714757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=8427618319490714757' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8427618319490714757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/8427618319490714757'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html' title='Your first component - Tutorial 2'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7705981707896961530</id><published>2008-12-31T10:55:00.013+02:00</published><updated>2009-03-31T12:18:40.952+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Services'/><title type='text'>Starting with OSGi - Tutorial 1</title><content type='html'>This is the first part of &lt;a href="http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html"&gt;a series of tutorials&lt;/a&gt; which show how you can build context-aware applications with the &lt;a href="http://nearchos.googlepages.com/musiccontextsystem"&gt;MUSIC Context System&lt;/a&gt;. This system is part of the general MUSIC Middleware, developed by the &lt;a href="http://www.ist-music.eu/"&gt;MUSIC Consortium&lt;/a&gt;. As the MUSIC Context System is built on top of &lt;a href="http://www.osgi.org/"&gt;OSGi&lt;/a&gt; and it leverages Declarative Services (which are  based on &lt;a href="http://www.humbertocervantes.net/servicebinder"&gt;Service Binder&lt;/a&gt;), we start with an introduction to these technologies. For an additional, well-structured tutorial on OSGi and Declarative services, you can also check out &lt;a href="http://neilbartlett.name/blog/osgi-articles"&gt;this blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;OSGi Component Framework Basics&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;Open Service Gateway initiative&lt;/span&gt; (OSGi) commonly refers to a standard specifying a Java-based service platform that can be remotely managed. The core part of the specifications is a framework that defines an application life cycle management model, a service registry, an Execution environment and Modules (see &lt;a href="http://en.wikipedia.org/wiki/OSGi"&gt;Wikipedia entry on OSGi&lt;/a&gt;). There are currently &lt;a href="http://www.osgi.org/Markets/Certified"&gt;five certified implementations&lt;/a&gt; complying to &lt;a href="http://www.osgi.org/Release4/HomePage"&gt;OSGi specification R4&lt;/a&gt;, including &lt;a href="http://www.eclipse.org/equinox"&gt;Eclipse Equinox&lt;/a&gt; and &lt;a href="http://www.makewave.com/"&gt;Knopflerfish&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As &lt;span style="font-style: italic;"&gt;component frameworks&lt;/span&gt;, OSGi implementations provide a way to encapsulate and package functionality into well-defined packages. In this case, the packages correspond to bundles, which can import and export services as a way of interacting with other bundles. These bundles are packaged in JAR files which enclose the Java classes of the implementing code, along with the required metadata (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the MANIFEST file).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Components and Services&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before we delve into the core of OSGi installation and use, we need to provide some additional explanation as per the motive for OSGi. Since the early 70's, computer scientists realized the importance of encapsulation (see &lt;a href="http://doi.acm.org/10.1145/361598.361623"&gt;this classic work from Parnas&lt;/a&gt; for example).&lt;br /&gt;&lt;br /&gt;Encapsulation allows implementing complex software with only a small fraction of it (the API) exposed to its users. This makes it possible to edit and update the internal implementation of the software without requiring any action from its users. In its most modern form, encapsulation (or information hiding) is enabled using &lt;a href="http://en.wikipedia.org/wiki/Component-based_software_engineering"&gt;components&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Service_%28systems_architecture%29"&gt;services&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One of the most popular definitions of software components specifies them as "&lt;span style="font-style: italic;"&gt;[software components] are units of composition with contractually specified interfaces and explicit context dependencies only; [software components] can be deployed independently and is subject to composition by third parties&lt;/span&gt;" (&lt;a href="http://research.microsoft.com/en-us/um/people/cszypers/Books/component-software.htm"&gt;&lt;span style="font-style: italic;"&gt;Component Software - Beyond Object-Oriented Programming&lt;/span&gt;&lt;/a&gt; book). On the other hand, services are used to indicate a predefined set of functionality through an interface (functional logic) along with some policies and/or contracts defining its extra-functional properties, such as &lt;span style="font-style: italic;"&gt;Quality of Service&lt;/span&gt; (QoS) contracts, etc.&lt;br /&gt;&lt;br /&gt;In OSGi, encapsulation is achieved via software components and services. The former can register (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, provide) or use (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, consume) services &lt;span style="font-style: italic;"&gt;dynamically&lt;/span&gt;, as needed. Services allow &lt;span style="font-style: italic;"&gt;loose coupling&lt;/span&gt; of components, &lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the &lt;span style="font-style: italic;"&gt;service providers&lt;/span&gt; do not know about their users and the &lt;span style="font-style: italic;"&gt;service users&lt;/span&gt; do not know about their providers. Notably, in OSGi the coupling is done dynamically (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, at runtime) which provides much more functionality and reliability to the systems.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Downloading and Installing the Framework&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;While there are multiple implementations of the OSGi specification, for the purposes of this tutorial we will use &lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt;'s &lt;a href="http://www.eclipse.org/equinox"&gt;Equinox&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Your first step is to download Equinox. At the time of writing this tutorial, version 3.4.1 is the latest one, and is available for download at this &lt;a href="http://download.eclipse.org/equinox/drops/R-3.4.1-200809111700/download.php?dropFile=eclipse-equinox-3.4.1.zip"&gt;link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Once it is downloaded, you should unzip the file to the folder of your choice (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, in "c:\", which creates the "c:\eclipse\..." folders).&lt;br /&gt;&lt;br /&gt;The core of the Equinox implementation of OSGi is in the "plugins" folder, in a JAR file named "org.eclipse.osgi_3.4 ... .jar". Copy that file to "c:\" and rename it to "equinox.jar".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Starting the OSGi Console&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To start the (console view) of the framework, simply issue the following command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;C:\eclipse&amp;gt;java -jar equinox.jar -console&lt;br /&gt;&lt;br /&gt;osgi&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The framework is up. You can issue your first command to the console. Try "help" or "ss". The first one prints a list of available commands. The second one, shows the &lt;span style="font-style: italic;"&gt;short status&lt;/span&gt; of the framework, as in the following:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This output says that there is only one bundle installed in the framework (the core OSGi implementation by Equinox), which is assigned the ID "0" and is currently "active". Each bundle can be further introspected with the "bundle" command, as follows:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; bundle 0&lt;br /&gt;System Bundle [0] Id=0, Status=RESOLVED&lt;br /&gt;Registered Services {org.eclipse.osgi.framework.console.CommandProvider}={service.ranking=2147483647, service.id=1} {org.eclipse.osgi.framework.log.FrameworkLog}={service.ranking=2147483647, service.pid=0.org.eclipse.core.runtime.adaptor.EclipseLog, service.vendor=Eclipse.org, service.id=4} {org.eclipse.osgi.framework.log.FrameworkLog}={service.ranking=-2147483648, performance=true, service.pid=46org.eclipse.core.runtime.adaptor.EclipseLog, service.vendor=Eclipse.org, service.id=5} {org.eclipse.osgi.service.runnable.ApplicationLauncher}={service.id=22}&lt;br /&gt;Services in use: {org.eclipse.osgi.framework.console.CommandProvider}={service.ranking=2147483647, service.id=1}&lt;br /&gt;No exported packages [PackageAdmin service is not registered]&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;As it was already mentioned in the OSGi Basics, bundles interact with each other via services. In this case, the services are abstracted and correspond to plain &lt;a href="http://en.wikipedia.org/wiki/Interface_%28Java%29"&gt;Java Interfaces&lt;/a&gt;. As such, each bundle specify a list of offered (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, registered) and needed (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, used) services. Notably, this status shows that the Equinox bundle offers (and uses) the "&lt;span style="font-family:courier new;"&gt;org.eclipse.osgi.framework.console.CommandProvider&lt;/span&gt;" interface. This is a service which allows interfacing with the &lt;span style="font-style: italic;"&gt;Command Line Interface&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, the console), and it will be revisited in one of  the following tutorials.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Getting ready for Declarative Services&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;While the current bundle is sufficient for the core OSGi, additional bundles are needed in order to add more functionality. For example, in order to deploy bundles which use Declarative Services, you need to install the following bundles: "org.eclipse.equinox.ds_1. ... .jar", "org.eclipse.equinox.util_1. ... .jar" and "org.eclipse.osgi.services_3. ... .jar".&lt;br /&gt;&lt;br /&gt;Please note that all the needed JAR files are available in the "./plugins" folder, and they can be installed by referencing them directly as follows:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; install file:plugins\org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar&lt;br /&gt;Bundle id is 1&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; install file:plugins\org.eclipse.equinox.util_1.0.0.v20080414.jar&lt;br /&gt;Bundle id is 2&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; install file:plugins\org.eclipse.osgi.services_3.1.200.v20071203.jar&lt;br /&gt;Bundle id is 3&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1 INSTALLED org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2 INSTALLED org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3 INSTALLED org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 1&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 2&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; start 3&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is launched.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;1 ACTIVE org.eclipse.equinox.ds_1.0.0.v20080427-0830&lt;br /&gt;2 ACTIVE org.eclipse.equinox.util_1.0.0.v20080414&lt;br /&gt;3 ACTIVE org.eclipse.osgi.services_3.1.200.v20071203&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Finally, please note that after you install a bundle, it is copied in "./configuration" (which is created by OSGi the first time you launch it) and thus it is not needed to keep it at the source folder anymore.&lt;br /&gt;&lt;br /&gt;In this case, we have started all the bundles and executed the &lt;span style="font-style: italic;"&gt;short status&lt;/span&gt; (ss) command afterwards.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Shutting the OSGi console down&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To exit the console, you can simply issue the "shutdown" command followed by "exit" command:&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;osgi&amp;gt; shutdown&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; ss&lt;br /&gt;&lt;br /&gt;Framework is shutdown.&lt;br /&gt;&lt;br /&gt;id State Bundle&lt;br /&gt;0 RESOLVED org.eclipse.osgi_3.4.2.R34x_v20080826-1230&lt;br /&gt;&lt;br /&gt;osgi&amp;gt; exit&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Homework 1.1&lt;/span&gt;: Run the "help" command in the console. Report what each of the following commands does:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;status&lt;/li&gt;&lt;li&gt;diag ID&lt;br /&gt;&lt;/li&gt;&lt;li&gt;h ID&lt;br /&gt;&lt;/li&gt;&lt;li&gt;services&lt;/li&gt;&lt;li&gt;packages&lt;br /&gt;&lt;/li&gt;&lt;li&gt;close&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Homework 1.2&lt;/span&gt;: Read the first chapter (Introduction) of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;Neil Bartlett's book&lt;/a&gt;. You can skip sections 1.3 and 1.8.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7705981707896961530?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7705981707896961530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7705981707896961530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7705981707896961530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7705981707896961530'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html' title='Starting with OSGi - Tutorial 1'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-528910741962245893</id><published>2008-12-30T15:23:00.021+02:00</published><updated>2009-02-12T19:38:47.973+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Declarative services'/><category scheme='http://www.blogger.com/atom/ns#' term='MUSIC-IST'/><title type='text'>Tutorials for OSGi, Declarative Services and the MUSIC Context System</title><content type='html'>As a research associate at the &lt;a href="http://www.ucy.ac.cy/"&gt;University of Cyprus&lt;/a&gt;, I work for the MUSIC-IST (somehow, the anagram for "&lt;a href="http://www.ist-music.eu/"&gt;&lt;span style="font-style: italic;"&gt;Self-Adapting Applications for Mobile Users in Ubiquitous Computing Environments&lt;/span&gt;&lt;/a&gt;"), which is an FP7 IP project funded by the European Union. It aims at enabling the development of context-aware, self adaptive applications. One of the most important novelties of MUSIC, is that it provides a &lt;span style="font-style: italic;"&gt;comprehensive development methodology&lt;/span&gt;. This means that the developers have a plethora of guidance, tools and libraries available when they depart developing such an application. Furthermore, as it is based on a Middleware architecture, MUSIC provides flexibility and facilitates code reuse.&lt;br /&gt;&lt;br /&gt;As part of my research, I am the principal architect and developer of the &lt;a href="http://nearchos.googlepages.com/musiccontextsystem"&gt;MUSIC Context System&lt;/a&gt;. In the following posts, I will describe how this system can be used to build context-aware applications. As this system builds on top of OSGi, and especially leverages the Declarative Services specification, the first tutorials cover the basics of OSGi, starting from installing and launching the framework. As new tutorials become available, I will update the list in this blog entry.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;OSGi and Declarative Services&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;Starting with OSGi - Tutorial 1&lt;/a&gt; (published Dec 31st, 2008) &lt;a href="http://nearchos.blogspot.com/2008/12/starting-with-osgi-tutorial-1.html"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2008/12/your-first-component-tutorial-2.html"&gt;Your first component - Tutorial 2&lt;/a&gt; (published Jan 1st, 2009)&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/binding-declarative-services-tutorial-3.html"&gt;Binding declarative services - Tutorial 3&lt;/a&gt; (published Jan 2nd, 2009)&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/interacting-with-cli-tutorial-4.html"&gt;Interacting with the CLI - Tutorial 4&lt;/a&gt; (published Jan 3rd, 2009)&lt;a href="http://nearchos.blogspot.com/2009/01/interacting-with-cli-tutorial-4.html"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/component-lifecycle-support-tutorial-5.html"&gt;Component lifecycle support - Tutorial 5&lt;/a&gt; (published Jan 4th, 2009)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;MUSIC Context System&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/introduction-to-music-context-system.html"&gt;Introduction to the MUSIC Context System - Tutorial 6&lt;/a&gt; (published Jan 7th, 2009)&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/music-context-model-tutorial-7.html"&gt;Context Model and Ontology - Tutorial 7&lt;/a&gt; (published Jan 28th, 2009)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/developing-your-first-context-sensor.html"&gt;Developing your first context sensor plug-in - Tutorial 8&lt;/a&gt; (published Jan 29th, 2009)&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/01/developing-context-client-tutorial-9.html"&gt;Developing a context client - Tutorial 9&lt;/a&gt; (published Jan 30th, 2009)&lt;/li&gt;&lt;li&gt;&lt;a href="http://nearchos.blogspot.com/2009/02/developing-complete-context-aware.html"&gt;Developing a complete context-aware application (CaMP) - Tutorial 10&lt;/a&gt; (published Feb 12th, 2009)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The only requirement for attending these tutorials is a &lt;span style="font-style: italic;"&gt;reasonable command of Object-Oriented programming in Java&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;For comments, or suggestions regarding these tutorials, please contact the author via email (you can find it in my homepage: &lt;a href="http://member.acm.org/%7Enearchos"&gt;http://member.acm.org/~nearchos&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Resources&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.osgi.org/"&gt;OSGi website&lt;/a&gt; and and the &lt;a href="http://www.osgi.org/Release4/HomePage"&gt;Specifications of Release 4 (R4)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Neil Bartlett's blog entries on &lt;a href="http://neilbartlett.name/blog/osgi-articles"&gt;Getting Started with OSGi&lt;/a&gt; and the first chapters of &lt;a href="http://neilbartlett.name/blog/osgibook"&gt;his book (in draft)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;A 6-page quick-start introduction to OSGi and Equinox (requires registration): &lt;a href="http://refcardz.dzone.com/announcements/equinox"&gt;Getting Started with Equinox and OSGi Refcard&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Andre L. C. Tavares, Marco Tulio Valente, &lt;a href="http://doi.acm.org/10.1145/1402521.1402526"&gt;&lt;span style="font-style: italic;"&gt;A Gentle Introduction to OSGi&lt;/span&gt;&lt;/a&gt;, &lt;i&gt;SIGSOFT Software Engineering Notes&lt;/i&gt;, Vol. 33, No. 5 (Aug. 2008), pp. 1-5&lt;/li&gt;&lt;li&gt;A few books by Amazon are unfortunately not available until Summer ("&lt;a href="http://www.amazon.com/Equinox-OSGi-Power-Behind-Eclipse/dp/0321585712"&gt;Equinox and OSGi&lt;/a&gt;" and "&lt;a href="http://www.amazon.com/OSGi-Action-Creating-Modular-Applications/dp/1933988916"&gt;OSGi in Action: Creating Modular Applications in Java&lt;/a&gt;")&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-528910741962245893?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/528910741962245893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=528910741962245893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/528910741962245893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/528910741962245893'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/12/tutorials-for-osgi-declarative-services.html' title='Tutorials for OSGi, Declarative Services and the MUSIC Context System'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-6409781734336295998</id><published>2008-12-29T21:14:00.000+02:00</published><updated>2009-01-29T11:38:22.842+02:00</updated><title type='text'>2nd Workshop on Context-aware Adaptation Mechanisms for Pervasive and Ubiquitous Services (CAMPUS 2009)</title><content type='html'>&lt;span style="font-size:100%;"&gt;Building on last year's success, the "&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://campus09.ifi.uio.no/"&gt;&lt;span style="font-style: italic;"&gt;2nd Workshop on Context-aware Adaptation Mechanisms for Pervasive and Ubiquitous Services&lt;/span&gt; &lt;/a&gt;&lt;a href="http://campus09.ifi.uio.no/"&gt;(CAMPUS 2009)&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;" will be organized again, in conjunction with the "&lt;a href="http://discotec09.di.fc.ul.pt/"&gt;&lt;span style="font-style: italic;"&gt;4th International federated conference on Distributed Computing Techniques&lt;/span&gt; (DisCoTec 2009)&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;As a member of the &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://campus09.ifi.uio.no/committees"&gt;Program Committee&lt;/a&gt; of the workshop, I encourage you to consider submitting any work you have done relevant to "Context-awareness" or "Adaptation Mechanisms" for Pervasive and Ubiquitous Services. I honestly think is a good forum, with experienced reviewers, for discussing and potentially presenting your work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Important dates:&lt;/span&gt;&lt;br /&gt;Paper submission: March 20, 2009&lt;br /&gt;Paper notification: April 24, 2009&lt;br /&gt;Camera ready: May 08, 2009&lt;br /&gt;Workshop: June 12, 2009&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-6409781734336295998?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/6409781734336295998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=6409781734336295998' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6409781734336295998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6409781734336295998'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2009/01/2nd-workshop-on-context-aware.html' title='2nd Workshop on Context-aware Adaptation Mechanisms for Pervasive and Ubiquitous Services (CAMPUS 2009)'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-2213901758016757413</id><published>2008-12-29T12:31:00.009+02:00</published><updated>2008-12-29T14:18:15.357+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Audio'/><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><category scheme='http://www.blogger.com/atom/ns#' term='iTunes'/><category scheme='http://www.blogger.com/atom/ns#' term='Pros and Cons'/><category scheme='http://www.blogger.com/atom/ns#' term='iPod touch'/><category scheme='http://www.blogger.com/atom/ns#' term='UI'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><title type='text'>iPod touch</title><content type='html'>As promised in a &lt;a href="http://nearchos.blogspot.com/2008/12/photos-from-hawaii.html"&gt;blog entry&lt;/a&gt; some weeks ago, I now post my impressions of iPod touch.&lt;br /&gt;&lt;br /&gt;I bought an iPod touch (2nd generation) as a gift to myself while we were visiting Hawaii. The &lt;a href="http://www.apple.com/retail/royalhawaiian/"&gt;Apple Store&lt;/a&gt; I got it from was great! So was the price ($230 plus tax), considering how much more expensive iPods are in Europe. Let me say here that I chose iPod to iPhone for two simple reasons: First, I already have a &lt;a href="http://europe.nokia.com/A4344227"&gt;NOKIA phone&lt;/a&gt; with which I am very happy and, second, I wanted a device primarily for browsing the Internet without a laptop and for killing my time in airports etc.&lt;br /&gt;&lt;br /&gt;The first impression was actually not very positive. I got frustrated because I could not get iPod paired with my iTunes account. The reason was that iTunes purchases are available only in selected countries (and Cyprus is not one them yet), which was OK with me. The problem was that although I did not mind not being able to buy staff (I have plenty of CDs already), I still wanted to be able to get the freely available products (mostly apps and podcasts). Thanks to instructions from &lt;a href="http://www.instructables.com/id/How-to-get-a-Free-Itunes-Account-No-Credit-Card-N/"&gt;this site&lt;/a&gt;, I was finally able to set up my iTunes account without having to enter any data for a credit card or mailing address (it is too bad Apple did not make it easier to skip attaching a credit card to an iTunes account).&lt;br /&gt;&lt;br /&gt;Other than this little glitch though, I have to admit that iPod touch is an amazing gadget. Most of all, I enjoy the touch UI, and the orientation sensors which add a lot to the user experience (especially in the context of game apps). MUSIC and video playback are excellent. In my last 4.5h flight back from &lt;a href="http://www.schiphol.nl/"&gt;Schiphol&lt;/a&gt;, I felt as if time flew by! I was using my iPod touch to watch video snippets of stand-up comedy from Comedy Central and also I was playing with what has become my favorite iPod game: &lt;a href="http://tapjoy.com/"&gt;TAP Defense&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I would like to also cover the development aspects of iPhone/iPod touch, but unfortunately I soon realized that the development tools for iPhone and iPod touc are limited to Macs only.&lt;br /&gt;&lt;br /&gt;In summary, the pros:&lt;br /&gt;1. Great UI&lt;br /&gt;2. Excellent web and mail applications&lt;br /&gt;3. Great audio and video playback&lt;br /&gt;4. The appstore is a vibrant active community generating challenging and useful apps&lt;br /&gt;5. As a device, it is small and light&lt;br /&gt;6. It charges from USB&lt;br /&gt;&lt;br /&gt;and cons:&lt;br /&gt;1. It does not have an embedded microphone&lt;br /&gt;2. Docking base comes as an extra&lt;br /&gt;3. Its accessories (e.g. docking station, video connector, power adapter) are quite expensive&lt;br /&gt;4. The Development tools are available for Macs only&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-2213901758016757413?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/2213901758016757413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=2213901758016757413' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2213901758016757413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2213901758016757413'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/12/ipod-touch.html' title='iPod touch'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-4732473082309355141</id><published>2008-12-28T19:53:00.010+02:00</published><updated>2008-12-29T12:29:35.148+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oahu'/><category scheme='http://www.blogger.com/atom/ns#' term='diamond head'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='hanauma'/><category scheme='http://www.blogger.com/atom/ns#' term='kailua'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='Hawaii'/><title type='text'>Photos from Hawaii</title><content type='html'>It's been more than a month since we visited Hawaii now. But I need to write this blog entry so that I don't forget how wonderful everything was. I think Oahu is a gorgeous island, even though I understand that the other islands of Hawaii might be even prettier (at least less developed = more natural).&lt;br /&gt;&lt;br /&gt;While Honolulu is a nice city, Waikiki is too touristic for my taste. But apart from this, the rest of the island is amazing. Even just outside the limits of the city, there are tropical forests and wonderful waterfalls. Just a few miles east of Honolulu, Hanauma bay, which is typically very busy, provides an astonishing experience. Then, the Polynesian Cultural Center to the northeast of the island is definitely worth visiting. Although the day we visited the Polynesian Cultural Center was quite rainy, it was still a quite memorable experience. And of course, the beaches  of Hawaii, especially Kailua, is a must visit/must swim activity for everyone visiting Oahu.&lt;br /&gt;&lt;br /&gt;I am looking forward to the next opportunity to visit Hawaii!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_C_OJecKV4yM/SVfLJBG3BvI/AAAAAAAAIWU/4GGRCifYfXw/s1600-h/Diamond+Head.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 85px;" src="http://1.bp.blogspot.com/_C_OJecKV4yM/SVfLJBG3BvI/AAAAAAAAIWU/4GGRCifYfXw/s320/Diamond+Head.jpg" alt="" id="BLOGGER_PHOTO_ID_5284916043519035122" border="0" /&gt;&lt;/a&gt;This and other pictures from Oahu are posted in my Picasa account: "&lt;a href="http://picasaweb.google.com/nearchos/OahuHawaii"&gt;Oahu, Hawaii&lt;/a&gt;".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-4732473082309355141?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/4732473082309355141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=4732473082309355141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4732473082309355141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/4732473082309355141'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/12/photos-from-hawaii.html' title='Photos from Hawaii'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_C_OJecKV4yM/SVfLJBG3BvI/AAAAAAAAIWU/4GGRCifYfXw/s72-c/Diamond+Head.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-5126429107674742922</id><published>2008-11-04T10:53:00.005+02:00</published><updated>2008-11-04T11:15:35.719+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GMail'/><category scheme='http://www.blogger.com/atom/ns#' term='touch-screen'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='Hawaii'/><category scheme='http://www.blogger.com/atom/ns#' term='family'/><category scheme='http://www.blogger.com/atom/ns#' term='iPod touch'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='gestures'/><title type='text'>Gearing up for Hawaii</title><content type='html'>Just a week before heading for Hawaii, I am all excited about visiting these tropical islands in the middle of the Pacific. Adding up to the big-brother-is-watching-me [1] feeling, GMail offered some Hawaii-related hotel offers while watching a completely unrelated message. Lucky guess, or does Google actually know more about me than I thought? I am sure that somewhere in the future, we will be able to query Google "where to is my next trip?" and receive the right answer!&lt;br /&gt;&lt;br /&gt;One of the many things I am anticipating to for this trip is shopping. Actually, I am always happy when I visit the States as there are always some things (usually gadgets) I would like to buy. This time, I have set my eyes on &lt;a href="http://store.apple.com/us/browse/home/shop_ipod/family/ipod_touch"&gt;iPod touch&lt;/a&gt;. As it has been almost five years since I bought my last iPod (2nd or 3rd generation, white with 20Gb disk), technology has progressed a lot. I am especially looking forward to the &lt;span style="font-style: italic;"&gt;touchscreen with gestures &lt;/span&gt;experience. Although I have considered iPhone too, I am going with iPod touch for several reasons: First, I am already quite happy with my Nokia E65 phone (we all know that Nokia &lt;span style="font-style: italic;"&gt;knows &lt;/span&gt;how to make good phones); Second, I hear that iPhone has some rough edges, at least wrt its phone aspects; Third, it is quite expensive to buy it in Europe and in the US it is locked and requires a 2-year contract. I will probably follow up with a blog with my experiences with iPod touch once I try it long enough.&lt;br /&gt;&lt;br /&gt;[1]. Actually, to me the "big brother" term is quite unsuccessful; &lt;span style="font-weight: bold;"&gt;my&lt;/span&gt; &lt;a href="http://haris.jappee.com/"&gt;big brother&lt;/a&gt; has always looked after me in the metaphorical sense only! I guess I am lucky :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-5126429107674742922?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/5126429107674742922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=5126429107674742922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/5126429107674742922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/5126429107674742922'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/11/gearing-up-for-hawaii.html' title='Gearing up for Hawaii'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-5838238564411040214</id><published>2008-09-17T16:24:00.005+03:00</published><updated>2008-09-19T09:25:15.332+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ubiquitous computing'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='phd research'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><title type='text'>Dude, where is my computer?</title><content type='html'>You know how you sometimes read an article somewhere and you think this is so cool, I should write a blog entry about this as well? Well, I do!&lt;br /&gt;&lt;br /&gt;I was just reading an article on &lt;a href="http://en.wikipedia.org/wiki/Cloud_computing"&gt;cloud computing&lt;/a&gt; in &lt;a href="http://www.spectrum.ieee.org/"&gt;IEEE Spectrum&lt;/a&gt; (by the way, an excellent magazine for technology lovers). This article, titled &lt;a href="http://www.spectrum.ieee.org/aug08/6490"&gt;&lt;span style="font-style: italic;"&gt;the cloud is the computer&lt;/span&gt;&lt;/a&gt;, discusses how &lt;span style="font-style: italic;"&gt;Paul McFedries&lt;/span&gt; (the author) expects &lt;span style="font-style: italic;"&gt;cloud computing&lt;/span&gt; to power the future of &lt;a href="http://en.wikipedia.org/wiki/Ubiquitous_computing"&gt;&lt;span style="font-style: italic;"&gt;pervasive (or ubiquitous) computing&lt;/span&gt;&lt;/a&gt;. This makes two of us! (Well, most likely more.)&lt;br /&gt;&lt;br /&gt;Being a researcher in pervasive computing technologies, and an active user of several cloud computing-based applications myself, has affected my thinking of how the future of computing could be. The original idea behind ubiquitous computing, as expressed by &lt;a href="http://en.wikipedia.org/wiki/Mark_Weiser"&gt;Mark Weiser&lt;/a&gt;, is for technologies that result to &lt;span style="font-style: italic;"&gt;computing receding to the background of our lives&lt;/span&gt;. In other words, the users continue receiving the &lt;span style="font-style: italic;"&gt;benefit&lt;/span&gt; of using their favorite services without necessarily having to bother about the actual machinery that offers them.&lt;br /&gt;&lt;br /&gt;If you think about it, when you connect to &lt;a href="http://mail.google.com/"&gt;GMail&lt;/a&gt; from your desktop's favorite browser, you do not bother about the complex machinery that is required to enable that. You rather concentrate on your goal, which in this case is textual communication. Later on in the day, when you access your account using &lt;a href="http://www.google.com/mobile/default/mail/"&gt;GMail for mobile&lt;/a&gt; on your smart-phone, you still have access to similar functionality, which (ideally) is adapted to your &lt;a href="http://en.wikipedia.org/wiki/Context_awareness"&gt;context&lt;/a&gt;. For instance, a smaller screen, lower bandwidth and a more constrained keyboard.&lt;br /&gt;&lt;br /&gt;Personally, I think that GMail is currently the most successful, and definitely the most widespread, example of a pervasive computing application. Although we are still not at the point where the service is experienced with absolute transparency of the machinery, still this is the best example of how truly useful pervasive computing will be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-5838238564411040214?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/5838238564411040214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=5838238564411040214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/5838238564411040214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/5838238564411040214'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/09/dude-where-is-my-computer.html' title='Dude, where is my computer?'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-1886469881196489745</id><published>2008-08-21T08:25:00.006+03:00</published><updated>2008-09-19T09:23:13.828+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='isd2008'/><category scheme='http://www.blogger.com/atom/ns#' term='Online tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Google Docs success story</title><content type='html'>As a member of the organizing committee of the &lt;a href="http://isd2008.cs.ucy.ac.cy/"&gt;17th International Conference on Information Systems Development (ISD 2008)&lt;/a&gt;, I spent some time  (and still do as of today) in updating the conference's website (the original pages were created by the &lt;a href="http://www.nuigalway.ie/"&gt;National University of Ireland, Galway&lt;/a&gt; for &lt;a href="http://isd2007.nuigalway.ie/"&gt;ISD2007&lt;/a&gt;, and we were granted the right to reuse them).&lt;br /&gt;&lt;br /&gt;During this exercise, I found that &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;, and especially the spreadsheet application is extremely useful. For instance, while the authors were registering and submitting the camera-ready version of their papers, we used a dynamically updated spreadsheet to indicate the &lt;a href="http://spreadsheets.google.com/pub?key=pXCNaDAANiijgAq8j7rIoRw&amp;amp;gid=0"&gt;status of their paper&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Furthermore, while filling in the slots for session chairs and forming the program, we used another &lt;a href="http://spreadsheets.google.com/pub?key=pXCNaDAANiij08b5VFn1qUQ"&gt;dynamically updated page&lt;/a&gt; which indicated which slots were empty. This page was updated in almost real time, as we edited the spreadsheet as soon as we handled the incoming emails and then the corresponding web-page was updated within minutes.&lt;br /&gt;&lt;br /&gt;Finally, an important aspect of each conference is the publication of its &lt;a href="http://isd2008.cs.ucy.ac.cy/statistics.html"&gt;statistics&lt;/a&gt;. In this regard, Google spreadsheets really rocks, not only because it allows to publish information dynamically, but also because it allows the creation of graphs which are also dynamically updated along with their associated data. For instance, we were able to publish a &lt;a href="http://spreadsheets.google.com/pub?key=pXCNaDAANiihUzIzHgquNNQ&amp;amp;oid=9&amp;amp;output=image"&gt;graph&lt;/a&gt; with information about the number of submitted papers per track, along with their acceptance ratio. Furthermore, using the nice gadgets available in the web application, we were also able to publish a map that illustrates the origin of the (affiliation of the) &lt;a href="http://spreadsheets.google.com/pub?key=pXCNaDAANiigWpo_4z5ktGw"&gt;authors of accepted papers&lt;/a&gt; and the &lt;a href="http://isd2008.cs.ucy.ac.cy/committee.html#world-distribution"&gt;program committee&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Evidently, although an excellent tool, Google Docs is not perfect yet. One limitation I found is that I could not insert isolated fields of information in my web-pages (&lt;span style="font-style: italic;"&gt;i.e.&lt;/span&gt;, corresponding to a single cell). For instance, in one of the spreadsheets, I maintain information like the total number of accepted papers (which changes as some authors withdraw theirs). Unfortunately, that number had to be hard-coded in HTML, because I could not find a way to insert isolated (but dynamically updated) fields in my page. I understand that this can be solved with a custom gadget (if not done already), but of course it would be nice if it was provided as a standard gadget.&lt;br /&gt;&lt;br /&gt;Although not perfect yet, Google Docs have really helped us with the organization of the conference, and I think this is something worth mentioning. As I really did not want to deal with anything but static HTML pages, Google Docs has proved to be an extremely useful tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-1886469881196489745?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/1886469881196489745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=1886469881196489745' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1886469881196489745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/1886469881196489745'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/08/google-docs-success-story.html' title='Google Docs success story'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-2524537126373379313</id><published>2008-08-19T10:40:00.008+03:00</published><updated>2008-09-19T09:23:54.994+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maps'/><category scheme='http://www.blogger.com/atom/ns#' term='Online tools'/><category scheme='http://www.blogger.com/atom/ns#' term='GPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Location'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Cyprus'/><title type='text'>Testing Google Maps for mobile again</title><content type='html'>Like I mentioned before, I am using Google Maps for mobile. While in my previous &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://nearchos.blogspot.com/2008/08/google-maps-in-cyprus.html"&gt;entry&lt;/a&gt;&lt;/span&gt; I praised the &lt;span style="font-style: italic;"&gt;accuracy&lt;/span&gt; of the automatic positioning feature, I soon found out that this is not always the case. While at the &lt;a href="http://maps.google.com/maps?hl=en&amp;amp;ie=UTF8&amp;amp;ll=35.145845,33.412449&amp;amp;spn=0.006325,0.013733&amp;amp;t=h&amp;amp;z=17"&gt;new campus of the University of Cyprus&lt;/a&gt;, my phone centered my location as shown in the following screen-shot:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_C_OJecKV4yM/SKp5Bo8Yv3I/AAAAAAAACn4/ZPjamrqgJ9I/s1600-h/BuenosAires_GoogleMapsMobile.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_C_OJecKV4yM/SKp5Bo8Yv3I/AAAAAAAACn4/ZPjamrqgJ9I/s320/BuenosAires_GoogleMapsMobile.jpg" alt="" id="BLOGGER_PHOTO_ID_5236130585849151346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It took some zooming out to realize that this is actually &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=&amp;amp;ie=UTF8&amp;amp;ll=-34.504293,-58.433533&amp;amp;spn=0.815963,1.757813&amp;amp;t=h&amp;amp;z=10"&gt;Buenos Aires&lt;/a&gt; :-) Only 12270 Km away ;-)&lt;br /&gt;&lt;br /&gt;Update: Today (September 17th, 2008) I tried again and this time it gave me a somewhat more accurate reading. Again from the University of Cyprus campus, it showed me at the &lt;a href="http://maps.google.com/maps?hl=en&amp;amp;ie=UTF8&amp;amp;ll=35.147793,33.370253&amp;amp;spn=0.003163,0.006866&amp;amp;t=h&amp;amp;z=18"&gt;headquarters&lt;/a&gt; of my carrier (&lt;a href="http://www.cytamobile-vodafone.com/"&gt;Cytamobile Vodafone&lt;/a&gt;) with an &lt;span style="font-style: italic;"&gt;accuracy &lt;/span&gt;of 5 Kms. This of course covers more or less the whole city of Nicosia. Well, at least the results were imrpoved by a magnitude of X2454!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-2524537126373379313?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/2524537126373379313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=2524537126373379313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2524537126373379313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/2524537126373379313'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/08/testing-google-maps-for-mobile-again.html' title='Testing Google Maps for mobile again'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_C_OJecKV4yM/SKp5Bo8Yv3I/AAAAAAAACn4/ZPjamrqgJ9I/s72-c/BuenosAires_GoogleMapsMobile.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-7982051537669005390</id><published>2008-08-12T08:52:00.005+03:00</published><updated>2008-08-12T09:16:26.878+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maps'/><category scheme='http://www.blogger.com/atom/ns#' term='GPS'/><category scheme='http://www.blogger.com/atom/ns#' term='Location'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Cyprus'/><title type='text'>Google Maps in Cyprus</title><content type='html'>I have been using &lt;a href="http://www.google.com/mobile/default/maps/"&gt;Google Maps for mobile&lt;/a&gt; for a while. Recently, I had to reset my &lt;a href="http://europe.nokia.com/e65"&gt;E65&lt;/a&gt; to install the latest firmware from NOKIA. When I reinstalled Google Maps, I apparently got a new version where the &lt;a href="http://www.google.com/support/mobile/bin/answer.py?answer=81869&amp;amp;topic=13541"&gt;My Location&lt;/a&gt; feature if finally working (in Cyprus). Interestingly, the results were quite accurate (at least while close to the center of Nicosia).&lt;br /&gt;&lt;br /&gt;If you own a supported device (most NOKIA smart-phones are supported), then check it out. Although the actual location is determined by inquiring the cell IDs via GSM, a WiFi or GPRS connection is needed for the map data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-7982051537669005390?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/7982051537669005390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=7982051537669005390' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7982051537669005390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/7982051537669005390'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/08/google-maps-in-cyprus.html' title='Google Maps in Cyprus'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4982860166412548129.post-6491848865734486609</id><published>2008-08-03T17:09:00.026+03:00</published><updated>2008-09-19T09:25:29.560+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='phd research'/><category scheme='http://www.blogger.com/atom/ns#' term='Humor'/><category scheme='http://www.blogger.com/atom/ns#' term='Cyprus'/><title type='text'>The beginning</title><content type='html'>This is the beginning of my blogging life. Actually the beginning of my English blogging life. I was &lt;a href="http://www.phigita.net/%7Enearchos"&gt;blogging in Greek&lt;/a&gt; before (and still do sometimes). But to enlarge my audience and allow more people to benefit from my &lt;span style="font-style: italic;"&gt;wisdom&lt;/span&gt;, I started this blog in English as well.&lt;br /&gt;&lt;br /&gt;Let me introduce myself. My name is Nearchos Paspallis and I was born and live in Cyprus (which is such a small and complicated country that people tend to add a link to its &lt;a href="http://www.wikipedia.org/wiki/Cyprus"&gt;Wikipedia entry&lt;/a&gt; when they first mention her).&lt;br /&gt;&lt;br /&gt;Back to myself, I spend most of my time in front of a computer screen. However, my tan (seen in my profile picture) is mostly natural due to sunlight I am exposed to during coffee breaks (rather than to LCD radiation). There are primarily two main reasons I spend this much time in front of my computer: First, I work as a researcher in Software Engineering (so, you could say it's because of my job). Second, I pursue a PhD in Computer Science.&lt;br /&gt;&lt;br /&gt;The motivation for this blog is that it will help me organize my [public] thoughts, and have an archive of them in case I need to recall them. For instance, I plan to blog about technical stuff, and also thoughts related to my PhD research (&lt;span style="font-style: italic;"&gt;e.g.&lt;/span&gt;, try-and-fail lessons). Hopefully my ideas and opinion will not be completely useless to everyone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4982860166412548129-6491848865734486609?l=nearchos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nearchos.blogspot.com/feeds/6491848865734486609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4982860166412548129&amp;postID=6491848865734486609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6491848865734486609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4982860166412548129/posts/default/6491848865734486609'/><link rel='alternate' type='text/html' href='http://nearchos.blogspot.com/2008/08/beginning.html' title='The beginning'/><author><name>Nearchos Paspallis</name><uri>http://www.blogger.com/profile/02205044501915297745</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://2.bp.blogspot.com/_C_OJecKV4yM/SV3jiXbBiqI/AAAAAAAAIYE/9qdBJiVjckI/S220/NearchosPaspallis2008_small.JPG'/></author><thr:total>0</thr:total></entry></feed>
