<?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-6983141563768732668</id><updated>2012-01-09T03:23:26.302-08:00</updated><category term='parser generator'/><category term='bison'/><category term='bnf'/><category term='flex'/><category term='rbtree gwt java canvas html5'/><title type='text'>Rafał Rusin's blog</title><subtitle type='html'>This blog covers topics around Open Source Java / C++ Programming for Industry. It includes some insights from my commercial experience with various projects, like Apache ODE, Apache ServiceMix ESB and others. I hope it will provide you a simple way for doing complex tasks in Java or C++ as well as an overview of what's going on in Open Source nowadays.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-2139107390701148446</id><published>2011-12-17T15:51:00.000-08:00</published><updated>2011-12-17T15:51:22.543-08:00</updated><title type='text'>Table viewer using JQuery plugin and JEE</title><content type='html'>&lt;a href="http://datatables.net"&gt;DataTables&lt;/a&gt; is a &lt;a href="http://jquery.com"&gt;JQuery&lt;/a&gt; plugin, facilitating building Ajax table editors. In this example, I show how to connect it to JEE backend, which is a simple Servlet. Backend exposes a table, stored as a Java List within Servlet instance. Data is served back in JSON format using &lt;a href="http://jackson.codehaus.org"&gt;Jackson library&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Example is deployed on Google App Engine, &lt;a href="http://datatablesjee.appspot.com"&gt;datatablesjee.appspot.com&lt;/a&gt;. Code is available on GitHub &lt;a href="http://github.com/rafalrusin/datatablesjee"&gt;github.com/rafalrusin/datatablesjee&lt;/a&gt;. &lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-x0E3RN5eBPc/Tu0gDcUnfrI/AAAAAAAAAHo/xHEhHIxHg_8/s1600/datatablesjee.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="288" width="400" src="http://4.bp.blogspot.com/-x0E3RN5eBPc/Tu0gDcUnfrI/AAAAAAAAAHo/xHEhHIxHg_8/s400/datatablesjee.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;First, we need to instantiate DataTables plugin within a html page. This is extremely easy, by using code below:&lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1491712.js?file=instantiate.js"&gt;&lt;/script&gt;AjaxSource parameter refers to Servlet URI, which handles requests for data.ServerSide argument is set to true, which means that backend will do sorting, filteringand pagination. This allows us to use large tables (&amp;gt;1000 rows) without performance problemson client side. &lt;br/&gt;&lt;br/&gt;Now, we need to implement backend. Servlet requires a doGet method, which needs to retrieve parameters sent from clientas an Ajax request. Those parameters describe search keyword, starting row and page sizeof a table. &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1491712.js?file=init.java"&gt;&lt;/script&gt;Then, we need to do filtering and sorting. I used a simple toString + contains methodson a single row in order to do filtering. Sorting is done via custom comparator, which sorts by given column number. Following code does the job: &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1491712.js?file=filtering.java"&gt;&lt;/script&gt;Last, we need to send JSON response back to client. Here, we use Jackson, which is a very convenient library for manipulating JSON in Java. &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1491712.js?file=result.java"&gt;&lt;/script&gt;iTotalRecords is total number of records, without filtering. iTotalDisplayRecords is number of records after applying filter. aaData is two dimensional array of strings, representing visible table data. &lt;br/&gt;&lt;br/&gt;Summing up, I like the idea of Ajax in this form, because client side isnot rendered directly by backend (no jsp, etc.). This makes it a detached view, which could be served as static content, from Apache Web Server for example, which is very performant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-2139107390701148446?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/2139107390701148446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/12/table-viewer-using-jquery-plugin-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/2139107390701148446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/2139107390701148446'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/12/table-viewer-using-jquery-plugin-and.html' title='Table viewer using JQuery plugin and JEE'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-x0E3RN5eBPc/Tu0gDcUnfrI/AAAAAAAAAHo/xHEhHIxHg_8/s72-c/datatablesjee.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-7001268197716939680</id><published>2011-11-13T03:01:00.000-08:00</published><updated>2011-11-13T03:01:23.950-08:00</updated><title type='text'>Running Qt4 Examples on Embedded Linux using ARM emulator</title><content type='html'>In this article I will show how to run Qt4-Embedded Examples on Angstrom Linux using QEMU. The procedure doesn't require any compilation or cross compilation. It uses Angstrom Linux precompiled packages, online image builder, and works both on Windows and Linux. &lt;br/&gt;Qt4 Embedded allows to run Qt applications directly in Linux Framebuffer, bypassing X Windows completely. This is especially important during embedded development, because it allows to save a lot of memory and start up time. &lt;br/&gt;&lt;br/&gt;Qt4 has a rich set of examples directly embedded into Qt sources. Below is a few samples of how it looks like: &lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jUm0ASwaFq0/Tr-hgg0YI2I/AAAAAAAAAG8/TzNh1CODlF8/s1600/path-stroking.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="315" width="400" src="http://4.bp.blogspot.com/-jUm0ASwaFq0/Tr-hgg0YI2I/AAAAAAAAAG8/TzNh1CODlF8/s400/path-stroking.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-tVh_Fr_p7zk/Tr-hlnMtt0I/AAAAAAAAAHI/ym51KOisNuQ/s1600/tetrix.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="315" width="400" src="http://1.bp.blogspot.com/-tVh_Fr_p7zk/Tr-hlnMtt0I/AAAAAAAAAHI/ym51KOisNuQ/s400/tetrix.png" /&gt;&lt;/a&gt;&lt;/div&gt;I will show how to run them.&lt;br/&gt;&lt;br/&gt;First, you need to install QEMU. For Windows, the easiest way is to download zipped executables, which I shared here: &lt;a href="http://www.4shared.com/folder/hjxINbny/embedded.html"&gt;Qemu-windows-0151&lt;/a&gt;. For Linux it's usually &lt;b&gt;apt-get install qemu-system&lt;/b&gt;. &lt;br/&gt;Then, we need to build Angstrom image. For those unpatient, I shared a prebuilt image here: &lt;a href="http://www.4shared.com/folder/hjxINbny/embedded.html"&gt;angstrom-qt4-embedded&lt;/a&gt;.Angstrom has online image builder available here: &lt;a href="http://narcissus.angstrom-distribution.org"&gt;Angstrom Image Builder&lt;/a&gt;. You need to pick console image and download it. The small trick is that you need to download kernel image yourself (from here: &lt;a href="http://feeds.angstrom-distribution.org/feeds/unstable/ipk/glibc/armv5te/machine/qemuarm/kernel-image-2.6.37.2_2.6.37-r4.6_qemuarm.ipk"&gt;kernel-image-2.6.37.2_2.6.37-r4.6_qemuarm.ipk&lt;/a&gt;) and unpack it using &lt;b&gt;ar -x kernel-image.ipk&lt;/b&gt; command. This is because online image builder doesn't include kernel image for some reason. However this step is not required if you download the image I shared. &lt;br/&gt;&lt;br/&gt;Next, you need to start QEMU using kernel image and prebuilt angstrom image. The command looks like this:&lt;br/&gt;&lt;b&gt;qemu-system-arm -M versatilepb -usb -usbdevice wacom-tablet -show-cursor -m 64 -kernel zImage-2.6.37.2 -hda disk.img -append "root=/dev/sda2 rw"&lt;/b&gt;&lt;br/&gt;For convenience, I prepared &lt;b&gt;run&lt;/b&gt; script, which does that. &lt;br/&gt;&lt;br/&gt;Next, you need to login as root and install qt4-embedded using command: &lt;b&gt;opkg install qt4-embedded&lt;/b&gt;. This can be again skipped if you use the image I prepared. &lt;/br&gt;&lt;br/&gt;In order to run demos, you need to use this command:&lt;br/&gt;&lt;b&gt;qtdemoE -qws&lt;/b&gt;&lt;br/&gt;It looks like this: &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-yMcGfePvTh0/Tr-fnEwUsTI/AAAAAAAAAGw/31Jk69Wji48/s1600/angstrom-console.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="472" width="600" src="http://2.bp.blogspot.com/-yMcGfePvTh0/Tr-fnEwUsTI/AAAAAAAAAGw/31Jk69Wji48/s400/angstrom-console.png" /&gt;&lt;/a&gt;&lt;/div&gt;You can run the other examples from Qt, in standalone mode from &lt;b&gt;/usr/bin/qtopia&lt;/b&gt; directory. You need to use similar command &lt;b&gt;app -qws&lt;/b&gt;. The command is required to initialize Qt framebuffer. It is possible to run a few executables on the same display. In order to do this, you need to run the first one only with &lt;b&gt;qws&lt;/b&gt; parameter. The other apps will connect to it.&lt;br/&gt;&lt;br/&gt;Have fun!&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-7001268197716939680?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/7001268197716939680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/11/running-qt4-examples-on-embedded-linux.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7001268197716939680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7001268197716939680'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/11/running-qt4-examples-on-embedded-linux.html' title='Running Qt4 Examples on Embedded Linux using ARM emulator'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-jUm0ASwaFq0/Tr-hgg0YI2I/AAAAAAAAAG8/TzNh1CODlF8/s72-c/path-stroking.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-6213226993797326225</id><published>2011-10-16T05:50:00.000-07:00</published><updated>2011-10-16T05:56:44.486-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rbtree gwt java canvas html5'/><title type='text'>Red Black Tree Visualization using HTML5 Canvas and GWT</title><content type='html'>I created a sample app, which demonstrates HTML5 Canvas usage from Java through GWT.I think GWT is a great tool for migrating desktop apps into Web nowadays, especiallyfor Java developers. So it's worth to give it a try. &lt;br/&gt;&lt;br/&gt;Google has made great progress on &lt;i&gt;migrating desktop apps into Web&lt;/i&gt; during last year.They propagated trend for HTML5 support and Javascript JIT compilers among modern browsers. So it's possible to run Quake 2 or CAD software directly in browser at decent speed. &lt;br/&gt;&lt;br/&gt;&lt;a href="http://en.wikipedia.org/wiki/Red%E2%80%93black_tree"&gt;Red Black Tree&lt;/a&gt; is a balanced BST tree. Details are described on Wikipedia. &lt;br/&gt;You can &lt;a href="http://rbvis123.appspot.com"&gt;run this sample app directly on appspot&lt;/a&gt; (it works on iPhone too :-) )&lt;br/&gt;Sample code can be found here:&lt;a href="http://github.com/rafalrusin/rbvis"&gt;Browse on GitHub&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;&lt;img src="http://sites.google.com/site/rrusin999/syntax/rbvis.png" width="600" height="224"/&gt;&lt;br/&gt;Let's start from initialization.&lt;br/&gt;First, we need to create Canvas element and add it to HTML. getContext2D is called to obtain drawing context.&lt;br/&gt;We register a timer to redraw frames frequently: &lt;br/&gt;&lt;script src="https://gist.github.com/1290819.js?file=init.java"&gt;&lt;/script&gt;&lt;br/&gt;So doUpdate is called every 50 ms and whenever redrawFrame is set to true, it redrawsCanvas contents. &lt;br/&gt;In autoplay mode, we call processFrame in while loop. So whenever redraw procedure takes too long, we will process frames without redrawing them. This won't slow down animation on low resources. &lt;br/&gt;&lt;script src="https://gist.github.com/1290819.js?file=processFrame.java"&gt;&lt;/script&gt;&lt;br/&gt;Then, we need to draw a tree. We use drawTree procedure, which is recursive and draws nodes along with contents and connections between them: &lt;br/&gt;&lt;script src="https://gist.github.com/1290819.js?file=drawTree.java"&gt;&lt;/script&gt;&lt;br/&gt;The best part is that we can do regular Java unit tests on Red Black tree to verify correctness of implementation:&lt;br/&gt;&lt;script src="https://gist.github.com/1290819.js?file=test.java"&gt;&lt;/script&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-6213226993797326225?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/6213226993797326225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/10/red-black-tree-visualization-using.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6213226993797326225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6213226993797326225'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/10/red-black-tree-visualization-using.html' title='Red Black Tree Visualization using HTML5 Canvas and GWT'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-7477084979409400198</id><published>2011-10-03T12:55:00.000-07:00</published><updated>2011-10-03T13:06:09.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='bnf'/><category scheme='http://www.blogger.com/atom/ns#' term='bison'/><category scheme='http://www.blogger.com/atom/ns#' term='parser generator'/><title type='text'>Grammar parser in C++</title><content type='html'>Recently I stumbled upon implementing a simple parser in C++. The task is very classic, however I couldn't find any good resources on the web to help me out. &lt;br/&gt;I tried different tools (including ANTLR), but finally the easiest way I found was bison + flex. It's unbelievable that this technology from 1989 is still actively developed. Latest stable release is from May 14, 2011. Moreover, many important projects make use of it. Among them are Ruby, PHP, Google Go, Bash shell.&lt;br/&gt;So I decided to create a minimalistic example, which works from scratch.&lt;br/&gt;I published the code on github &lt;a href="http://github.com/rafalrusin/calculator"&gt;Calculator&lt;/a&gt;, so you can check it out.&lt;br/&gt;The whole example is 88 lines long and evaluates common expressions, like 2+2*2-13*(7+19/2).&lt;br/&gt;Let's start with lexer. In flex, you need to define regular expressions, which produce tokens. Such tokens are later processed by a scanner. So we have to define calculator.lex, like this: &lt;br/&gt;&lt;script src="https://gist.github.com/1259974.js?file=calculator.lex"&gt;&lt;/script&gt;&lt;br/&gt;Flex will generate yylex() function, which we can call later to produce tokens. &lt;br/&gt;Next, we need to create a scanner (calculator.y), which specifies a grammar. It's simple like that:&lt;br/&gt;&lt;script src="https://gist.github.com/1259974.js?file=calculator.y"&gt;&lt;/script&gt;&lt;br/&gt;Here, we specify types for all tokens using C/C++ union like structure. Variable $$ is used to store result of particular reductions. &lt;br/&gt;Additionally, we need to specify %left precedence for +, -, *, / operators to resolve shift / reduce conflicts between them. &lt;br/&gt;And that's basically it. We have a working expression parser. &lt;br/&gt; I implemented it in a way, that executable takes a file name containing expressions as an argument.&lt;br/&gt;So you can try ./calculator input.txt to see the result.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-7477084979409400198?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/7477084979409400198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/10/grammar-parser-in-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7477084979409400198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7477084979409400198'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/10/grammar-parser-in-c.html' title='Grammar parser in C++'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-1147189098693472736</id><published>2011-06-12T15:20:00.000-07:00</published><updated>2011-06-12T15:20:38.582-07:00</updated><title type='text'>Visualizing GIS data in JavaFX 2.0 beta using GeoTools</title><content type='html'>Geographic data mostly comprises of polygon coordinates sets along with attributes, like country or city name, etc. This is quite easy to visualize in JavaFX, which supports rendering for SVG paths. &lt;br/&gt;In the article, I show how to read such GIS data from ESRI type database files using open source library &lt;a href="http://geotools.org"&gt;GeoTools&lt;/a&gt;. &lt;br/&gt;The data itself comes for free from &lt;a href="http://www.naturalearthdata.com"&gt;www.naturalearthdata.com&lt;/a&gt;.&lt;br/&gt;Sample code can be found here:&lt;a href="http://github.com/rafalrusin/geotools-fx-test"&gt;Browse on GitHub&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;&lt;img src="http://sites.google.com/site/rrusin999/syntax/geotools-fx-test.png" width="569" height="442"/&gt;&lt;br/&gt;&lt;br/&gt;GIS data usually comes in form of SHP and DBF files. In order to read it, we use GeoTools parser. Following code iterates over so called "features" from within data filesand retrieves name attribute and shape geometry. &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1022034.js?file=iterating.java"&gt;&lt;/script&gt;&lt;br/&gt;Next, we need to create JavaFX polygons for each feature from iteration. Small note here. Each feature may comprise of multiple polygons. For example "United States" shape may contain separate polygon for Alaska. So we need additional loop to generate such polygons.&lt;br/&gt;In order to create a polygon in JavaFX, we use Path class along with MoveTo and LineTo path elements. Following snippet does the job. &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1022034.js?file=polygons.java"&gt;&lt;/script&gt;&lt;br/&gt;The remaining part is to implement zoom and panning functionality. This is fairly easyin JavaFX. We can use translate and scale properties from main Group shape. Panning functionality is handled using following snippet:&lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1022034.js?file=panning.java"&gt;&lt;/script&gt;&lt;br/&gt;Zoom is coded this way:&lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/1022034.js?file=zoom.java"&gt;&lt;/script&gt;&lt;br/&gt;That's it. Now we have basic GIS data viewer in JavaFX 2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-1147189098693472736?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/1147189098693472736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/06/visualizing-gis-data-in-javafx-20-beta.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/1147189098693472736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/1147189098693472736'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/06/visualizing-gis-data-in-javafx-20-beta.html' title='Visualizing GIS data in JavaFX 2.0 beta using GeoTools'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-4336881801082893168</id><published>2011-03-22T16:03:00.000-07:00</published><updated>2011-03-22T16:03:36.739-07:00</updated><title type='text'>Implementing graph editor in JavaFX using MVC like approach</title><content type='html'>JavaFX has very good SVG support, embedded into language runtime. This makes it interesting choice for implementing custom UI components, which includes graph editors. &lt;br/&gt;In this article, I show how to create a simple graph editor, using MVC like approach and XML serialization via XStream. &lt;br/&gt;&lt;br/&gt;Example can be found here:&lt;a href="http://sites.google.com/site/rrusin999/syntax/netflow.jnlp"&gt;Launch JNLP&lt;/a&gt;,&lt;a href="http://github.com/rafalrusin/javafx"&gt;Browse on GitHub&lt;/a&gt;.&lt;br/&gt;Application brings graph editing functionality and maximum network flow computation using &lt;a href="http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm"&gt;Ford Fulkerson algorithm&lt;/a&gt; &lt;br/&gt;&lt;br/&gt;&lt;img src="http://sites.google.com/site/rrusin999/syntax/netflow.png" width="569" height="442"/&gt;&lt;br/&gt; &lt;br/&gt;Architecture is divided into Model, View and Controller. I made a slight upgrade to classic understanding of MVC. Classic View was responsible for displaying data only. Here, View consists also of UI parts, which include editable labels or combo boxes. Also, in Classic MVC, Model was responsible for refreshing View after Model changes by sending events to registered views. Here, Controller is responsible for refreshing View after Model changes and Model is just a plain POJO structure. I found such approach easier to implement. &lt;br/&gt; &lt;br/&gt;&lt;b&gt;Model&lt;/b&gt; consists of Three Java classes (non JavaFX), which represent structure of a graph: MNode, MShape, MConnection. Separating those classes from UI gives benefit of easier serialization. In this case using XStream::toXML(model) does the job. Sample output is like this: &lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/882258.js?file=model.xml"&gt;&lt;/script&gt; &lt;br/&gt;&lt;b&gt;View&lt;/b&gt; consists of corresponding UI implementations for Model elements, which are UINode, UILine, UIShape. Here, UINode is connected to MNode through model property. This is &lt;a href="http://en.wikipedia.org/wiki/Bridge_pattern"&gt;Bridge Pattern&lt;/a&gt; like approach for splitting class hierarchy of nodes into two.  &lt;br/&gt;UINode classes refer to controller to perform user input actions, like delete node.  &lt;br/&gt; &lt;br/&gt;&lt;b&gt;Controller&lt;/b&gt; implements user action logic. This includes add, delete, and drag node. It is also responsible for refreshing UI after model changes. In order to do that easily, it uses Weak Hash Map, which keys are Model nodes and values are UI Nodes. Update function is like this:&lt;br/&gt;&lt;br/&gt;&lt;script src="https://gist.github.com/882258.js?file=netflow.fx"&gt;&lt;/script&gt;Because of Weak Hash Map, removing nodes from Model leads to removing corresponding UI elements from map automaticly. &lt;br/&gt;&lt;br/&gt;JavaFX SVG support and Layouts make it easy to render quite good looking nodes and connections. &lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-4336881801082893168?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/4336881801082893168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/03/implementing-graph-editor-in-javafx.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/4336881801082893168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/4336881801082893168'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/03/implementing-graph-editor-in-javafx.html' title='Implementing graph editor in JavaFX using MVC like approach'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-6391723176461125973</id><published>2011-03-07T13:42:00.000-08:00</published><updated>2011-03-07T13:56:55.046-08:00</updated><title type='text'>Drawing arrows in JavaFX</title><content type='html'>Some time in the past, I was wondering what's the easiest solution for drawing arrowconnections between shapes. The problem boils down to computing boundary point for given shape, which intersects with connecting line. &lt;br/&gt;The solution is not so difficult when we consider polygon shapes. But it becomes more difficult considering curves and far more difficult for generic SVG shapes. &lt;br/&gt;In this article, I show a simple way to find such boundary points for generic SVG shapes, utilizing JavaFX "contains" method and simple bisection algorithm. &lt;br/&gt;Following application does the job: &lt;a href="http://sites.google.com/site/rrusin999/syntax/arrows.jnlp"&gt;Launch JNLP&lt;/a&gt;,&lt;a href="http://github.com/rafalrusin/javafx"&gt;Browse on GitHub&lt;/a&gt;.&lt;br/&gt;Application allows to drag shapes to track shape boundaries.&lt;br/&gt;&lt;img src="http://sites.google.com/site/rrusin999/syntax/arrows.png" width="410" height="314"/&gt;&lt;br/&gt;So, "contains" method in JavaFX allows us to poll any 2D point for intersection with SVG shape.Next, we need to assume, that we know a point inside a shape, from which every ray has exactly one intersection. This includes star-like shapes and ellipses. Next, we can use simple bisection algorithm to find such boundary point. We cut off once length between two points is too small. Following snippet does the job:&lt;script src="http://gist.github.com/859239.js?file=bisect.fx"&gt;&lt;/script&gt;Next, we need to draw arrows on the ends. In order to do that, we can use JavaFX Affine Transform, which is matrix transformation for SVG path. We need to compute transformation vectors for the matrix. This sounds scarry, but in fact is relatively easy. First vector in matrix is (targetPoint - sourcePoint) / length. Second one is perpendicular to it. Following code applies transformation:&lt;script src="http://gist.github.com/859239.js?file=affine"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-6391723176461125973?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/6391723176461125973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2011/03/drawing-arrows-in-javafx.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6391723176461125973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6391723176461125973'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2011/03/drawing-arrows-in-javafx.html' title='Drawing arrows in JavaFX'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-435042312219769179</id><published>2010-10-23T15:10:00.001-07:00</published><updated>2010-10-23T15:10:29.228-07:00</updated><title type='text'>Apache HISE + Apache Camel</title><content type='html'>Check out this SlideShare Presentation: &lt;div style="width:425px" id="__ss_5540260"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/rrusin/apache-hise-apache-camel" title="Apache HISE + Apache Camel"&gt;Apache HISE + Apache Camel&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse5540260" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hise-101023164306-phpapp02&amp;stripped_title=apache-hise-apache-camel&amp;userName=rrusin" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5540260" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hise-101023164306-phpapp02&amp;stripped_title=apache-hise-apache-camel&amp;userName=rrusin" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/rrusin"&gt;Rafal Rusin&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-435042312219769179?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/435042312219769179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/10/apache-hise-apache-camel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/435042312219769179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/435042312219769179'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/10/apache-hise-apache-camel.html' title='Apache HISE + Apache Camel'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-3214120969579514837</id><published>2010-07-18T16:06:00.000-07:00</published><updated>2010-07-18T16:06:26.001-07:00</updated><title type='text'>jetty webapp osgi way</title><content type='html'>I will show how to expose simple Jetty OSGi service and use it to register hello world webapp. This app will serve static content from OSGi bundle and implement sample request handler under ServiceMix 4.Code is available here: &lt;a href="http://github.com/rafalrusin/jetty-service"&gt;http://github.com/rafalrusin/jetty-service&lt;/a&gt;    &lt;br/&gt;    Alternative solutions are: using standard OSGi HTTP service &lt;a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/http/HttpService.html"&gt;http://www.osgi.org/javadoc/r4v42/org/osgi/service/http/HttpService.html&lt;/a&gt;to register servlet; and wrap existing WAR application using PAX WEB &lt;a href="http://wiki.ops4j.org/display/paxweb/Pax+Web"&gt;http://wiki.ops4j.org/display/paxweb/Pax+Web&lt;/a&gt;.I won't consider those two, since Jetty itself provides flexible way to handle webapps (including registering servlets). So those two are unnecessary overhead and are less flexible. Anyway those two are usually implemented on top of Jetty.&lt;br/&gt;So the first thing to do is to create Jetty OSGi service. Basicly it will be a Spring Bean exposed to OSGi. Following snippet does the job:&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="hl kwb"&gt;id&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt; &lt;span class="hl kwb"&gt;class&lt;/span&gt;=&lt;span class="hl str"&gt;"org.apache.jetty.service.JettyServiceImpl"&lt;/span&gt; &lt;span class="hl kwb"&gt;init-method&lt;/span&gt;=&lt;span class="hl str"&gt;"init"&lt;/span&gt; &lt;span class="hl kwb"&gt;destroy-method&lt;/span&gt;=&lt;span class="hl str"&gt;"destroy"&lt;/span&gt;&lt;span class="hl kwa"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;osgi:service&lt;/span&gt; &lt;span class="hl kwb"&gt;id&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service-osgi"&lt;/span&gt; &lt;span class="hl kwb"&gt;ref&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt; &lt;span class="hl kwb"&gt;interface&lt;/span&gt;=&lt;span class="hl str"&gt;"org.apache.jetty.service.api.JettyService"&lt;/span&gt; &lt;span class="hl kwa"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;This will expose jetty-service to OSGi. All other components, which connect to it will wait automaticly until it's registered.Exposed interface has following methods:&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwc"&gt;Handler&lt;/span&gt; &lt;span class="hl kwd"&gt;registerApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;String&lt;/span&gt; name&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwc"&gt;Handler&lt;/span&gt; handler&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;unregisterApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Handler&lt;/span&gt; handler&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Those will be invoked to register Hello World application. JettyServiceImpl on the other hand, starts embedded Jetty Server and handles apps registration.&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;package&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;.&lt;/span&gt;api&lt;span class="hl sym"&gt;.&lt;/span&gt;JettyService&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwc"&gt;Handler&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;Server&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;ContextHandler&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;ContextHandlerCollection&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;public class&lt;/span&gt; JettyServiceImpl &lt;span class="hl kwa"&gt;implements&lt;/span&gt; JettyService &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;private&lt;/span&gt; Server server&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;private&lt;/span&gt; ContextHandlerCollection rootContext&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;init&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  server &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;Server&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;8080&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  rootContext &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;ContextHandlerCollection&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setHandler&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;rootContext&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;start&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;destroy&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;stop&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwc"&gt;Handler&lt;/span&gt; &lt;span class="hl kwd"&gt;registerApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;String&lt;/span&gt; name&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwc"&gt;Handler&lt;/span&gt; handler&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;stop&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;  ContextHandler h &lt;span class="hl sym"&gt;=&lt;/span&gt; rootContext&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addContext&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"/"&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; name&lt;span class="hl sym"&gt;,&lt;/span&gt; name&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  h&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setHandler&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;handler&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;start&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;return&lt;/span&gt; h&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;unregisterApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Handler&lt;/span&gt; handler&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;stop&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;  rootContext&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;removeHandler&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;handler&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  server&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;start&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Next step is to implement sample web app. First, we need to connect jetty-service bean to make it visible in our app.&lt;pre class="hl"&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;osgi:reference&lt;/span&gt; &lt;span class="hl kwb"&gt;id&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt; &lt;span class="hl kwb"&gt;interface&lt;/span&gt;=&lt;span class="hl str"&gt;"org.apache.jetty.service.api.JettyService"&lt;/span&gt; &lt;span class="hl kwb"&gt;bean-name&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt;&lt;span class="hl kwa"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="hl kwb"&gt;class&lt;/span&gt;=&lt;span class="hl str"&gt;"org.apache.jetty.service.example.HelloWorld"&lt;/span&gt; &lt;span class="hl kwb"&gt;init-method&lt;/span&gt;=&lt;span class="hl str"&gt;"init"&lt;/span&gt; &lt;span class="hl kwb"&gt;destroy-method&lt;/span&gt;=&lt;span class="hl str"&gt;"destroy"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="hl kwb"&gt;name&lt;/span&gt;=&lt;span class="hl str"&gt;"jettyService"&lt;/span&gt; &lt;span class="hl kwb"&gt;ref&lt;/span&gt;=&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt;&lt;span class="hl kwa"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Then, we need to implement sample app. &lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;package&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;.&lt;/span&gt;example&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; java&lt;span class="hl sym"&gt;.&lt;/span&gt;io&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwc"&gt;IOException&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; javax&lt;span class="hl sym"&gt;.&lt;/span&gt;servlet&lt;span class="hl sym"&gt;.&lt;/span&gt;ServletException&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; javax&lt;span class="hl sym"&gt;.&lt;/span&gt;servlet&lt;span class="hl sym"&gt;.&lt;/span&gt;http&lt;span class="hl sym"&gt;.&lt;/span&gt;HttpServletRequest&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; javax&lt;span class="hl sym"&gt;.&lt;/span&gt;servlet&lt;span class="hl sym"&gt;.&lt;/span&gt;http&lt;span class="hl sym"&gt;.&lt;/span&gt;HttpServletResponse&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;.&lt;/span&gt;api&lt;span class="hl sym"&gt;.&lt;/span&gt;JettyService&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;.&lt;/span&gt;util&lt;span class="hl sym"&gt;.&lt;/span&gt;BundleResource&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwc"&gt;Handler&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;HttpConnection&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwc"&gt;Request&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;AbstractHandler&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;ContextHandler&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;ContextHandlerCollection&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; org&lt;span class="hl sym"&gt;.&lt;/span&gt;mortbay&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;handler&lt;span class="hl sym"&gt;.&lt;/span&gt;ResourceHandler&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;public class&lt;/span&gt; HelloWorld &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;private&lt;/span&gt; JettyService jettyService&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;private&lt;/span&gt; &lt;span class="hl kwc"&gt;Handler&lt;/span&gt; registered&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;setJettyService&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;JettyService jettyService&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;this&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;jettyService &lt;span class="hl sym"&gt;=&lt;/span&gt; jettyService&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;init&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  ContextHandlerCollection handler &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;ContextHandlerCollection&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  handler&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addContext&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"/app"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;"app"&lt;/span&gt;&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;setHandler&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;AbstractHandler&lt;/span&gt;&lt;span class="hl sym"&gt;() {&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;handle&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;String&lt;/span&gt; target&lt;span class="hl sym"&gt;,&lt;/span&gt; HttpServletRequest request&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;br /&gt;     HttpServletResponse response&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwb"&gt;int&lt;/span&gt; arg3&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;IOException&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;br /&gt;     ServletException &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;          response&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setContentType&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"text/html"&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;          response&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setStatus&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;HttpServletResponse&lt;span class="hl sym"&gt;.&lt;/span&gt;SC_OK&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;          response&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getWriter&lt;/span&gt;&lt;span class="hl sym"&gt;().&lt;/span&gt;&lt;span class="hl kwd"&gt;println&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"&amp;lt;h1&amp;gt;Hello World from Java&amp;lt;/h1&amp;gt;"&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; request&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getParameterMap&lt;/span&gt;&lt;span class="hl sym"&gt;());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span class="hl kwc"&gt;Request&lt;/span&gt; base_request &lt;span class="hl sym"&gt;= (&lt;/span&gt;request &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; &lt;span class="hl kwc"&gt;Request&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt; ? &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Request&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;request&lt;span class="hl sym"&gt;:&lt;/span&gt;HttpConnection&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getCurrentConnection&lt;/span&gt;&lt;span class="hl sym"&gt;().&lt;/span&gt;&lt;span class="hl kwd"&gt;getRequest&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;          base_request&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setHandled&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;true&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl sym"&gt;});&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  ResourceHandler resourceHandler &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;ResourceHandler&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;  resourceHandler&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setBaseResource&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;BundleResource&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwd"&gt;getClass&lt;/span&gt;&lt;span class="hl sym"&gt;().&lt;/span&gt;&lt;span class="hl kwd"&gt;getResource&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"/static"&lt;/span&gt;&lt;span class="hl sym"&gt;)));&lt;/span&gt;&lt;br /&gt;  ContextHandler contextHandler &lt;span class="hl sym"&gt;=&lt;/span&gt; handler&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addContext&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;""&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl str"&gt;""&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  contextHandler&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setHandler&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;resourceHandler&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  registered &lt;span class="hl sym"&gt;=&lt;/span&gt; jettyService&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;registerApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"helloWorld"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; handler&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;destroy&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;  jettyService&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;unregisterApp&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;registered&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt; &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Here, we register sample request handler at 'app' sub path and serve static content from jar using BundleResource. Last thing is registering app using jettyService under 'helloWorld' context. So our application will be exposed under &lt;a href="http://localhost:8080/helloWorld/"&gt;http://localhost:8080/helloWorld/&lt;/a&gt; address.&lt;br/&gt;ServiceMix has also so called features. This is the way to collect multiple dependencies under a single name. So we have to create features.xml file, like this:&lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;features&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;feature name&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl str"&gt;"jetty-service"&lt;/span&gt; version&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl str"&gt;"${project.version}"&lt;/span&gt;&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;bundle&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;mvn&lt;span class="hl sym"&gt;:&lt;/span&gt;org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;/&lt;/span&gt;service&lt;span class="hl sym"&gt;/&lt;/span&gt;$&lt;span class="hl sym"&gt;{&lt;/span&gt;project&lt;span class="hl sym"&gt;.&lt;/span&gt;version&lt;span class="hl sym"&gt;}&amp;lt;/&lt;/span&gt;bundle&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;&amp;lt;/&lt;/span&gt;feature&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;feature name&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl str"&gt;"example-jetty-service-helloworld"&lt;/span&gt; version&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl str"&gt;"${project.version}"&lt;/span&gt;&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;feature version&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl str"&gt;"${project.version}"&lt;/span&gt;&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;jetty&lt;span class="hl sym"&gt;-&lt;/span&gt;service&lt;span class="hl sym"&gt;&amp;lt;/&lt;/span&gt;feature&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;bundle&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;mvn&lt;span class="hl sym"&gt;:&lt;/span&gt;org&lt;span class="hl sym"&gt;.&lt;/span&gt;apache&lt;span class="hl sym"&gt;.&lt;/span&gt;jetty&lt;span class="hl sym"&gt;.&lt;/span&gt;service&lt;span class="hl sym"&gt;/&lt;/span&gt;example&lt;span class="hl sym"&gt;-&lt;/span&gt;helloworld&lt;span class="hl sym"&gt;/&lt;/span&gt;$&lt;span class="hl sym"&gt;{&lt;/span&gt;project&lt;span class="hl sym"&gt;.&lt;/span&gt;version&lt;span class="hl sym"&gt;}&amp;lt;/&lt;/span&gt;bundle&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;&amp;lt;/&lt;/span&gt;feature&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;&amp;lt;/&lt;/span&gt;features&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Basicly, we can provide particular dependencies for our project.&lt;br/&gt;Next, we do 'mvn install' on our project and run apache-servicemix-4.2.0-fuse-01-00/bin/servicemix karaf console. On the console, we need to type following commands:&lt;pre class="hl"&gt;&lt;br /&gt;features:addUrl mvn:org.apache.jetty.service/service-karaf/0.1.0-SNAPSHOT/xml/features&lt;br /&gt;features:install example-jetty-service-helloworld&lt;br /&gt;osgi:list&lt;br /&gt;&lt;br /&gt;[ 230] [Active     ] [            ] [Started] [   60] Unnamed - org.apache.jetty.service:service:bundle:0.1.0-SNAPSHOT (0.1.0.SNAPSHOT)&lt;br /&gt;[ 231] [Active     ] [            ] [Started] [   60] Unnamed - org.apache.jetty.service:example-helloworld:bundle:0.1.0-SNAPSHOT (0.1.0.SNAPSHOT)&lt;/pre&gt;&lt;br/&gt;Now, we can enter &lt;a href="http://localhost:8080/helloWorld/"&gt;http://localhost:8080/helloWorld/&lt;/a&gt; to test our app. &lt;br/&gt;And that's it. OSGi and ServiceMix 4 features enable easy way to use dynamic modules in web apps. For example, it's veryeasy to build simple web framework with loadable components on page (something like mini implementation of Portlets). &lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-3214120969579514837?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/3214120969579514837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/07/jetty-webapp-osgi-way.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3214120969579514837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3214120969579514837'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/07/jetty-webapp-osgi-way.html' title='jetty webapp osgi way'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-859346365298205761</id><published>2010-07-10T09:54:00.000-07:00</published><updated>2010-07-10T09:54:02.066-07:00</updated><title type='text'>Integration Tests for SMX4 with Python</title><content type='html'>Integration tests and unit tests are important for project quality.         Unit tests usually are well suited for developer to verify his changes in runtime.         On the other hand, integration tests, are for target user to verify that project's features in the way he interacts with project,         work properly.        In this article, I will show how to automate integration tests for ServiceMix 4 using SoapUI testrunner and a simple python script.    &lt;br/&gt;            The idea is to spawn ServiceMix 4 Karaf console and interact with it using python expect library. During this interaction,         SoapUI testrunner script is invoked in order to run SoapUI tests.    &lt;br/&gt;    First, we need to grab SMX4_DIR and SOAPUI_DIR environment variables in our script, like this:    &lt;pre class="hl"&gt;&lt;br /&gt;SMX4_DIR&lt;span class="hl sym"&gt;=&lt;/span&gt;os&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getenv&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"SMX4_DIR"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;SOAPUI_DIR&lt;span class="hl sym"&gt;=&lt;/span&gt;os&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getenv&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"SOAPUI_DIR"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;This way, we can invoke later our script using following shell command:    &lt;pre class="hl"&gt;&lt;br /&gt;SMX4_DIR&lt;span class="hl sym"&gt;=/&lt;/span&gt;some&lt;span class="hl sym"&gt;/&lt;/span&gt;path SOAPUI_DIR&lt;span class="hl sym"&gt;=/&lt;/span&gt;some&lt;span class="hl sym"&gt;/&lt;/span&gt;other&lt;span class="hl sym"&gt;/&lt;/span&gt;path .&lt;span class="hl sym"&gt;/&lt;/span&gt;our&lt;span class="hl sym"&gt;-&lt;/span&gt;python&lt;span class="hl sym"&gt;-&lt;/span&gt;&lt;span class="hl kwc"&gt;script&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Then, we need to spawn ServiceMix 4 console by using python expect library:    &lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; pexpect&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; time&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; sys&lt;br /&gt;child &lt;span class="hl sym"&gt;=&lt;/span&gt; pexpect&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;spawn&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"bin/servicemix"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;logfile &lt;span class="hl sym"&gt;=&lt;/span&gt; sys&lt;span class="hl sym"&gt;.&lt;/span&gt;stdout&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;expect&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"karaf.*&amp;gt;"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;time&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sleep&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;3&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Here, we set logfile to stdout in order to see our automated interaction with ServiceMix console. Then we need to wait for ServiceMix console command prompt, which would mean console is ready. Additionally, we need to wait a few seconds to avoid problems with running commands too early (which is a kind of small bug in ServiceMix). Then, we can install our features, which we want to test. This example starts Apache HISE test bundle, which loads also Apache HISE engine from dependencies.     &lt;pre class="hl"&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sendline&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"features:addUrl mvn:org.apache.hise/hise-karaf/0.3.0-SNAPSHOT/xml/features"&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;expect&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"karaf.*&amp;gt;"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sendline&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"features:install hise-h2-test-example-osgi"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;expect&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"karaf.*&amp;gt;"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Next, we need to wait until the feature is properly started. ServiceMix 4 OSGi container initializes bundles in background, so it's not enough to wait for command prompt to have it started (there doesn't seem to exist a "wait-until-started" console command).So we grep in a loop over installed bundles and see if status is started. In this example, we do 30 retries every second and fail our integration test script after this period, by raising exception.    &lt;pre class="hl"&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sendline&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"features:addUrl mvn:org.apache.hise/hise-karaf/0.3.0-SNAPSHOT/xml/features"&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;rep&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl num"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;while True&lt;/span&gt;&lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;br /&gt;    child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sendline&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"osgi:list|grep -i hise-test-example-osgi"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;    l&lt;span class="hl sym"&gt;=&lt;/span&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;readline&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    l&lt;span class="hl sym"&gt;=&lt;/span&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;readline&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;if&lt;/span&gt; re&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;match&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;".*Started"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; l&lt;span class="hl sym"&gt;) !=&lt;/span&gt; &lt;span class="hl kwa"&gt;None&lt;/span&gt;&lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;break&lt;/span&gt;&lt;br /&gt;    time&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sleep&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;    child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;expect&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"karaf.*&amp;gt;"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;    rep&lt;span class="hl sym"&gt;=&lt;/span&gt;rep&lt;span class="hl sym"&gt;+&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;if&lt;/span&gt; rep&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;30&lt;/span&gt;&lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;raise&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"Bundle not installed"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Next, we need to run SoapUI testrunner in order to execute test cases. We need to implement syscall method in order to fail integration tests if SoapUI testrunner completes with fault (non-zero exit code).     &lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;import&lt;/span&gt; os&lt;br /&gt;&lt;span class="hl kwa"&gt;def&lt;/span&gt; &lt;span class="hl kwd"&gt;syscall&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;c&lt;span class="hl sym"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;if&lt;/span&gt; os&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;system&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;c&lt;span class="hl sym"&gt;) !=&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;raise&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"Sys call failed: "&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; c&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwd"&gt;syscall&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;SOAPUI_DIR &lt;span class="hl sym"&gt;+&lt;/span&gt; &lt;span class="hl str"&gt;"/bin/testrunner.sh -f results hise-soapui-project.xml"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;At the end, we can exit gracefully from ServiceMix console by using shutdown command, like this:    &lt;pre class="hl"&gt;&lt;br /&gt;child&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;sendline&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"shutdown"&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;  &lt;br/&gt;And that's it. Full code of integration test script is available in Apache HISE sources, from Apache repository &lt;a href="http://svn.apache.org/repos/asf/incubator/hise/trunk/itest/itest"&gt;http://svn.apache.org/repos/asf/incubator/hise/trunk/itest/itest&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-859346365298205761?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/859346365298205761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/07/integration-tests-for-smx4-with-python.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/859346365298205761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/859346365298205761'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/07/integration-tests-for-smx4-with-python.html' title='Integration Tests for SMX4 with Python'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-3570415965836881422</id><published>2010-06-24T17:47:00.000-07:00</published><updated>2010-06-24T17:47:07.303-07:00</updated><title type='text'>Apache ODE 1.3.4 released</title><content type='html'>Apache ODE 1.3.4 has been released recently. You can grab it from here &lt;a href="http://ode.apache.org/getting-ode.html"&gt;http://ode.apache.org/getting-ode.html&lt;/a&gt;.It has a few new features and a lot of bugfixes. &lt;br/&gt; &lt;br/&gt;First of new features is Instance Replayer (&lt;a href="http://ode.apache.org/instance-replayer"&gt;http://ode.apache.org/instance-replayer&lt;/a&gt;).In short, it's able to restore business process instance by reexecuting every step again based on incoming and outgoing instance communication (it mocks up outgoing requests). &lt;br/&gt;The basic use cases for replayer are:&lt;br/&gt;1. migrate existing log running instances to newest process versiongiven their communication (incoming and outgoing requests)&lt;br/&gt;2. reproduce error scenarios between two instances of ODE (eg.production and development)&lt;br/&gt;Instance Replayer extends management api by 2 operations: replay and getCommunication.In order to do 1, you can invoke following request:   &lt;pre class="hl"&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;pmap:replay&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;&amp;lt;replay&amp;gt;&lt;/span&gt;&lt;br /&gt;           &lt;span class="hl kwa"&gt;&amp;lt;ns:upgradeInstance&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;1234&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/ns:upgradeInstance&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;&amp;lt;/replay&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;/pmap:replay&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;You get a new instance in the newest process version. The old one will be deleted.&lt;br/&gt;In order to do 2, you need to retrieve exchanges from existing instance (or instances) by following request:   &lt;pre class="hl"&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;pmap:getCommunication&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;&amp;lt;getCommunication&amp;gt;&lt;/span&gt;&lt;br /&gt;           &lt;span class="hl kwa"&gt;&amp;lt;ns:iid&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;1234&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/ns:iid&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;&amp;lt;/getCommunication&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;/pmap:getCommunication&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Then, you can execute replay operation on another ODE installation in order to replicate instance:   &lt;pre class="hl"&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;pmap:replay&lt;/span&gt; xmlns:&lt;span class="hl kwb"&gt;ns&lt;/span&gt;=&lt;span class="hl str"&gt;"http://www.apache.org/ode/pmapi/types/2006/08/02/"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="hl kwa"&gt;&amp;lt;replay&amp;gt;&lt;/span&gt;&lt;br /&gt;           &lt;span class="hl kwa"&gt;&amp;lt;ns:restoreInstance&amp;gt;&lt;/span&gt;&lt;br /&gt;           &lt;span class="hl kwa"&gt;&amp;lt;ns:processType&lt;/span&gt;&lt;br /&gt;xmlns:&lt;span class="hl kwb"&gt;p&lt;/span&gt;=&lt;span class="hl str"&gt;"http://sample.bpel.org/bpel/sample"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;p:OnEventCorrelation&lt;span class="hl kwa"&gt;&amp;lt;/ns:processType&amp;gt;&lt;/span&gt;&lt;br /&gt;           ... exchanges&lt;br /&gt;           &lt;span class="hl kwa"&gt;&amp;lt;/ns:restoreInstance&amp;gt;&lt;/span&gt;&lt;br /&gt;       &lt;span class="hl kwa"&gt;&amp;lt;/replay&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;/pmap:replay&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;In order to have time control in bpel process, there is introduced special variable$ode:currentEventDateTime. It's equivalent to $fn:current-dateTime() standard XPath functionduring live session (while no replaying takes place) and it's set to corresponding time in past duringreplaying.&lt;br/&gt; &lt;br/&gt;The next new feature is SMX4 OSGi bundle distibution. Some detailed information on how to configure it is here: &lt;a href="http://ode.apache.org/smx4-osgi-deployment.html"&gt;http://ode.apache.org/smx4-osgi-deployment.html&lt;/a&gt;.In short, it's possible to deploy ODE and processes as OSGi bundles in ServiceMix4. This simplifies project structure compared to ServiceAssembly and ServiceUnit double zipped packages.&lt;br/&gt; &lt;br/&gt;Third feature is small, but may be useful. It makes possible to define Spring properties and use them inside business process. All you need to do is to put beans.xml file in process directory (example is here: &lt;a href="http://svn.apache.org/repos/asf/ode/tags/APACHE_ODE_1.3.4/jbi/src/test/resources/SpringPropertiesJbiTest/"&gt;http://svn.apache.org/repos/asf/ode/tags/APACHE_ODE_1.3.4/jbi/src/test/resources/SpringPropertiesJbiTest/&lt;/a&gt;).You need to define bean of name properties, like this:   &lt;pre class="hl"&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;beans&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;util:properties&lt;/span&gt; &lt;span class="hl kwb"&gt;id&lt;/span&gt;=&lt;span class="hl str"&gt;"properties"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;prop&lt;/span&gt; &lt;span class="hl kwb"&gt;key&lt;/span&gt;=&lt;span class="hl str"&gt;"weirdProp"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;myWeirdPropValue2&lt;span class="hl kwa"&gt;&amp;lt;/prop&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;/util:properties&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;ODE will instantiate it and you can use it later, like this:   &lt;pre class="hl"&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;&amp;lt;bpws:assign&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl kwa"&gt;&amp;lt;bpws:copy&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;bpws:from&amp;gt;&lt;/span&gt;ode:process-property('weirdProp')&lt;span class="hl kwa"&gt;&amp;lt;/bpws:from&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="hl kwa"&gt;&amp;lt;bpws:to&amp;gt;&lt;/span&gt;$output.payload&lt;span class="hl kwa"&gt;&amp;lt;/bpws:to&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl kwa"&gt;&amp;lt;/bpws:copy&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;&amp;lt;/bpws:assign&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-3570415965836881422?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/3570415965836881422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/06/apache-ode-134-released.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3570415965836881422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3570415965836881422'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/06/apache-ode-134-released.html' title='Apache ODE 1.3.4 released'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-6661870771724770961</id><published>2010-02-23T07:37:00.001-08:00</published><updated>2010-02-23T07:37:02.579-08:00</updated><title type='text'>Git, Beginner to Advanced Survey</title><content type='html'>Check out this SlideShare Presentation: &lt;div style="width:425px;text-align:left" id="__ss_3255219"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/rrusin/git-beginner-to-advanced-survey" title="Git, Beginner to Advanced Survey"&gt;Git, Beginner to Advanced Survey&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=git-100223061944-phpapp01&amp;stripped_title=git-beginner-to-advanced-survey" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=git-100223061944-phpapp01&amp;stripped_title=git-beginner-to-advanced-survey" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/rrusin"&gt;Rafal Rusin&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-6661870771724770961?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/6661870771724770961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/02/git-beginner-to-advanced-survey.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6661870771724770961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/6661870771724770961'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/02/git-beginner-to-advanced-survey.html' title='Git, Beginner to Advanced Survey'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-4164230652127853388</id><published>2010-01-19T14:11:00.000-08:00</published><updated>2010-02-19T03:52:31.654-08:00</updated><title type='text'>xquery4j in action</title><content type='html'>In my previous article, I introduced a wrapper library for Saxon, xquery4j &lt;a href="http://github.com/rafalrusin/xquery4j"&gt;http://github.com/rafalrusin/xquery4j&lt;/a&gt;.&lt;br/&gt;Here, I will explain how to use it to create an article generator in Java and XQuery for XHTML, called Article. You can download it here: &lt;a href="http://github.com/rafalrusin/Article"&gt;http://github.com/rafalrusin/Article&lt;/a&gt;. It's a simple DSL for article generation.&lt;br/&gt;&lt;br /&gt;        I think it is something worth noticing, because the whole project took me just a while to implement and has interesting features. Those are:&lt;br /&gt;        &lt;ul xmlns:a="urn:article"&gt;            &lt;li&gt;embedded code syntax highlighting for a lot of programming languages (using external program highlight), &lt;/li&gt;            &lt;li&gt;creating href entries for links, so you don't need to type URL twice&lt;/li&gt;            &lt;li&gt;it integrates natively with XHTML constructs&lt;/li&gt;        &lt;/ul&gt;    &lt;br/&gt;This is an example of an input it takes:&lt;br/&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;&amp;lt;a:article&lt;/span&gt; xmlns='http://www.w3.org/&lt;span class="hl num"&gt;1999&lt;/span&gt;/xhtml' xmlns:&lt;span class="hl kwb"&gt;a&lt;/span&gt;=&lt;span class="hl str"&gt;"urn:article"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;a:l&amp;gt;&lt;/span&gt;Some text&lt;span class="hl kwa"&gt;&amp;lt;/a:l&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;a:code&lt;/span&gt; &lt;span class="hl kwb"&gt;lang&lt;/span&gt;=&lt;span class="hl str"&gt;"xml"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&amp;lt;![CDATA[&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;someXml/&amp;gt;&lt;/span&gt;&lt;br /&gt;]]&lt;span class="hl kwa"&gt;&amp;gt;&amp;lt;/a:code&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/a:article&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;It generates XHTML output for it, using command&lt;br/&gt;&lt;pre class="hl"&gt;.&lt;span class="hl sym"&gt;/&lt;/span&gt;run &lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;input.xml &lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt;output.xhtml&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;The interesting thing is that XQuery expression for this transformation is very simple to do in Saxon. This is the complete code of it:&lt;br/&gt;&lt;pre class="hl"&gt;declare namespace &lt;span class="hl kwb"&gt;a&lt;/span&gt;=&lt;span class="hl str"&gt;"urn:article"&lt;/span&gt;;&lt;br /&gt;declare default element namespace &lt;span class="hl str"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;declare function a:processLine($l) {&lt;br /&gt;for $i in $l/node()&lt;br /&gt;return&lt;br /&gt;typeswitch ($i)&lt;br /&gt;  case element(a:link, xs:untyped) return &lt;span class="hl kwa"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="hl kwb"&gt;href&lt;/span&gt;=&lt;span class="hl str"&gt;"{$i/text()}"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;{$i/text()}&lt;span class="hl kwa"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;br /&gt;  default return $i&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;declare function a:articleItem($i) {&lt;br /&gt;typeswitch ($i)&lt;br /&gt; case element(a:l, xs:untyped) return (a:processLine($i), &lt;span class="hl kwa"&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt; case element(a:code, xs:untyped) return&lt;br /&gt;  ( a:highlight($i/text(), $i/@lang)/body/* , &lt;span class="hl kwa"&gt;&amp;lt;br/&amp;gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt; default return &lt;span class="hl str"&gt;"error;"&lt;/span&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="hl kwb"&gt;xmlns&lt;/span&gt;=&lt;span class="hl str"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;a.xml&lt;span class="hl kwa"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="hl kwb"&gt;rel&lt;/span&gt;=&lt;span class="hl str"&gt;"stylesheet"&lt;/span&gt; &lt;span class="hl kwb"&gt;type&lt;/span&gt;=&lt;span class="hl str"&gt;"text/css"&lt;/span&gt; &lt;span class="hl kwb"&gt;href&lt;/span&gt;=&lt;span class="hl str"&gt;"highlight.css"&lt;/span&gt;&lt;span class="hl kwa"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;for $i in a:article/*&lt;br /&gt;return&lt;br /&gt;a:articleItem($i)&lt;br /&gt;}&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Inside this expression, there is bound a:highlight Java function, which takes two strings on input (a code and a language) and returns DOM Node containing XHTML output from highlight command.&lt;br/&gt;Since there is not much trouble with manipulating DOM using xquery4j, we can get as simple solution as this for a:highlight function:&lt;br/&gt;&lt;pre class="hl"&gt;    &lt;span class="hl kwa"&gt;public static class&lt;/span&gt; Mod &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;public static&lt;/span&gt; &lt;span class="hl kwc"&gt;Node&lt;/span&gt; &lt;span class="hl kwd"&gt;highlight&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;final&lt;/span&gt; &lt;span class="hl kwc"&gt;String&lt;/span&gt; code&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwc"&gt;String&lt;/span&gt; lang&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; &lt;span class="hl kwc"&gt;Exception&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;            Validate&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;notNull&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;lang&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl kwa"&gt;final&lt;/span&gt; &lt;span class="hl kwc"&gt;Process&lt;/span&gt; p &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwc"&gt;ProcessBuilder&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"highlight"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;"-X"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;"--syntax"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; lang&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;start&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl kwc"&gt;Thread&lt;/span&gt; t &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwc"&gt;Thread&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwc"&gt;Runnable&lt;/span&gt;&lt;span class="hl sym"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                &lt;span class="hl kwa"&gt;public&lt;/span&gt; &lt;span class="hl kwb"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;run&lt;/span&gt;&lt;span class="hl sym"&gt;() {&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl kwa"&gt;try&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;                        &lt;span class="hl kwc"&gt;OutputStream&lt;/span&gt; out &lt;span class="hl sym"&gt;=&lt;/span&gt; p&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getOutputStream&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;                        IOUtils&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;write&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;code&lt;span class="hl sym"&gt;,&lt;/span&gt; out&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;                        out&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;flush&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;                        out&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;close&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;catch&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;IOException&lt;/span&gt; e&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;                        &lt;span class="hl kwa"&gt;throw new&lt;/span&gt; &lt;span class="hl kwc"&gt;RuntimeException&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;e&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;                    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;                &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl sym"&gt;});&lt;/span&gt;&lt;br /&gt;            t&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;start&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl kwc"&gt;String&lt;/span&gt; result &lt;span class="hl sym"&gt;=&lt;/span&gt; IOUtils&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;toString&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;p&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;getInputStream&lt;/span&gt;&lt;span class="hl sym"&gt;());&lt;/span&gt;&lt;br /&gt;            t&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;join&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl kwa"&gt;return&lt;/span&gt; DOMUtils&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;parse&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;result&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getDocumentElement&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Please note that creating a separate thread for feeding input into highlight command is required, since Thread's output queue is limited and potentially might lead to dead lock. So we need to concurrently collect output from spawned Process.&lt;br/&gt;However at the end, when we need to convert a String to DOM and we use xquery4j's DOMUtils.parse(result), so it's a very simple construct.&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-4164230652127853388?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/4164230652127853388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/01/xquery4j-in-action.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/4164230652127853388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/4164230652127853388'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/01/xquery4j-in-action.html' title='xquery4j in action'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-7594550166246467171</id><published>2010-01-16T14:11:00.000-08:00</published><updated>2010-01-18T13:36:24.247-08:00</updated><title type='text'>Embedding XQuery in Java</title><content type='html'>XQuery is a very powerful language. It can be very useful when you want to do some XML processing in Java.&lt;br/&gt;Let's say you want to create an XML document  based on some other XML data. Given something like this:&lt;br/&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;&amp;lt;employees&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;employee&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Fred Jones&lt;span class="hl kwa"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="hl kwb"&gt;location&lt;/span&gt;=&lt;span class="hl str"&gt;"home"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;street&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;900&lt;/span&gt; Aurora Ave.&lt;span class="hl kwa"&gt;&amp;lt;/street&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;city&amp;gt;&lt;/span&gt;Seattle&lt;span class="hl kwa"&gt;&amp;lt;/city&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;state&amp;gt;&lt;/span&gt;WA&lt;span class="hl kwa"&gt;&amp;lt;/state&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;zip&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;98115&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/zip&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;address&lt;/span&gt; &lt;span class="hl kwb"&gt;location&lt;/span&gt;=&lt;span class="hl str"&gt;"work"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;street&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;2011 152&lt;/span&gt;nd Avenue NE&lt;span class="hl kwa"&gt;&amp;lt;/street&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;city&amp;gt;&lt;/span&gt;Redmond&lt;span class="hl kwa"&gt;&amp;lt;/city&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;state&amp;gt;&lt;/span&gt;WA&lt;span class="hl kwa"&gt;&amp;lt;/state&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;&amp;lt;zip&amp;gt;&lt;/span&gt;&lt;span class="hl num"&gt;98052&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/zip&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;/address&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;phone&lt;/span&gt; &lt;span class="hl kwb"&gt;location&lt;/span&gt;=&lt;span class="hl str"&gt;"work"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;(&lt;span class="hl num"&gt;425&lt;/span&gt;)&lt;span class="hl num"&gt;555&lt;/span&gt;-&lt;span class="hl num"&gt;5665&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/phone&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;phone&lt;/span&gt; &lt;span class="hl kwb"&gt;location&lt;/span&gt;=&lt;span class="hl str"&gt;"home"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;(&lt;span class="hl num"&gt;206&lt;/span&gt;)&lt;span class="hl num"&gt;555&lt;/span&gt;-&lt;span class="hl num"&gt;5555&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/phone&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;&amp;lt;phone&lt;/span&gt; &lt;span class="hl kwb"&gt;location&lt;/span&gt;=&lt;span class="hl str"&gt;"mobile"&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;gt;&lt;/span&gt;(&lt;span class="hl num"&gt;206&lt;/span&gt;)&lt;span class="hl num"&gt;555&lt;/span&gt;-&lt;span class="hl num"&gt;4321&lt;/span&gt;&lt;span class="hl kwa"&gt;&amp;lt;/phone&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;/employee&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="hl kwa"&gt;&amp;lt;/employees&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;You want to produce employees' names:&lt;br/&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;&amp;lt;names&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Fred Jones&lt;span class="hl kwa"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/names&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;In XQuery it's just as easy as:&lt;br/&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;&amp;lt;names&amp;gt;&lt;/span&gt;&lt;br /&gt;  {for $name in employees/employee/name/text() return &lt;span class="hl kwa"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;{$name}&lt;span class="hl kwa"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;}&lt;br /&gt;&lt;span class="hl kwa"&gt;&amp;lt;/names&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;The most interesting advantage for XQuery over various other methods for generating XML is that XQuery operates natively on XML.&lt;br/&gt;There are tools like JaxB, XmlBeans, which enable strongly typed XML building directly from Java code. But using such approach often requires a lot of Java code to be written, which is not really necessary.&lt;br/&gt;There is also a possibility to use XPath. However it's an inferior solution to XQuery, because XPath doesn't provide a way for building XML documents. It's designed only for nodes selection. On the other hand, XQuery extends XPath, so it supports every construct that XPath does.&lt;br/&gt;Another way to do such processing in Java is to use XSLT. It's the closest approach to XQuery. But the problem with XSLT is that it has its language constructs, like 'for' expressed as XML elements. This makes writing XSLT code much more difficult that XQuery.&lt;br/&gt;XQuery can be seen as a native template language for XML processing.&lt;br/&gt;So the question is: how to evaluate XQuery expressions the best way from Java?&lt;br/&gt;There are some Open Source implementations of XQuery for Java. One of them is inside XmlBeans. However in my opinion the best way is to use Saxon. It's the most mature project for XQuery processing and it's targetted directly for doing that.&lt;br/&gt;However Saxon might be a bit difficult to use directly. At least digging a few interesting features from it took me some time.&lt;br/&gt;So I decided to write a simple class for interfacing Saxon and to provide a few interesting examples of how to use it. That's how xquery4j was born. You can download it from github &lt;a href="http://github.com/rafalrusin/xquery4j" xmlns:a="urn:article"&gt;http://github.com/rafalrusin/xquery4j&lt;/a&gt;.&lt;br/&gt;In xquery4j, you can execute XQuery expressions from Java in a simple way:&lt;br/&gt;&lt;pre class="hl"&gt;XQueryEvaluator evaluator &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;XQueryEvaluator&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwc"&gt;Long&lt;/span&gt; result &lt;span class="hl sym"&gt;= (&lt;/span&gt;&lt;span class="hl kwc"&gt;Long&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt; evaluator&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;evaluateExpression&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"5+5"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; null&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;get&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;Assert&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;assertEquals&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwc"&gt;Long&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;10&lt;/span&gt;&lt;span class="hl sym"&gt;),&lt;/span&gt; result&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;It's possible to bind variables from Java objects, the easy way:&lt;br/&gt;&lt;pre class="hl"&gt;evaluator&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;bindVariable&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;QName&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;valueOf&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"myVar"&lt;/span&gt;&lt;span class="hl sym"&gt;),&lt;/span&gt; &lt;span class="hl num"&gt;123&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Sometimes it's also useful to declare Java methods and bind them for XQuery expressions. This is also very simple to do with xquery4j:&lt;br/&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;public static class&lt;/span&gt; MyFunctions &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;public static&lt;/span&gt; &lt;span class="hl kwc"&gt;String&lt;/span&gt; &lt;span class="hl kwd"&gt;myHello&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;String&lt;/span&gt; arg&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;            TestEvaluator te &lt;span class="hl sym"&gt;= (&lt;/span&gt;TestEvaluator&lt;span class="hl sym"&gt;)&lt;/span&gt; XQueryEvaluator&lt;span class="hl sym"&gt;.&lt;/span&gt;contextObjectTL&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;get&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;            te&lt;span class="hl sym"&gt;.&lt;/span&gt;id&lt;span class="hl sym"&gt;++;&lt;/span&gt;&lt;br /&gt;            &lt;span class="hl kwa"&gt;return&lt;/span&gt; &lt;span class="hl str"&gt;"hello("&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; arg &lt;span class="hl sym"&gt;+&lt;/span&gt; te&lt;span class="hl sym"&gt;.&lt;/span&gt;id &lt;span class="hl sym"&gt;+&lt;/span&gt; &lt;span class="hl str"&gt;")"&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    XQueryEvaluator evaluator &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwd"&gt;XQueryEvaluator&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;    evaluator&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;setContextObject&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;this&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;    evaluator&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;declareJavaClass&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl str"&gt;"http://my.org/employees"&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; MyFunctions&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwa"&gt;class&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;This code sets a context object to 'this' and binds all static methods from MyFunctions class to XQuery expressions. So during myHello execution from XQuery, you can easily operate on Java variables from bound context - 'id' in this case.&lt;br /&gt;Here's a way of invoking such bound myHello method from XQuery:&lt;br/&gt;&lt;pre class="hl"&gt;declare namespace my = 'http://my.org/employees'; my:myHello(&lt;span class="hl str"&gt;"hello"&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;xquery4j code contains unit tests, which include examples above.&lt;br/&gt;You can run them by:&lt;br/&gt;&lt;pre class="hl"&gt;mvn package&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;Feel free to give some feedback on using it.&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-7594550166246467171?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/7594550166246467171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2010/01/embedding-xquery-in-java.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7594550166246467171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/7594550166246467171'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2010/01/embedding-xquery-in-java.html' title='Embedding XQuery in Java'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-5767679488326961376</id><published>2009-12-08T12:53:00.000-08:00</published><updated>2009-12-08T12:53:20.744-08:00</updated><title type='text'>ODEO new release</title><content type='html'>Recently, I released a new version 1.1.34 of ODEO (it's ODE tuned for Oracle and ServiceMix).&lt;br /&gt;You can check details (and downloads) here: &lt;a href="http://top.touk.pl/confluence/display/top/ODEO"&gt;http://top.touk.pl/confluence/display/top/ODEO.&lt;/a&gt;&lt;br /&gt;This version contains yet another set of fixes, which drive your BPEL engine more robust and useful for production use.&lt;br /&gt;Recent improvements include: faster redeployment for high-load installations, priorities for jobs and digests for compiled processes (which enable substitution of xpaths in processes and have old instances continued in new version).&lt;br /&gt;There are also some bug fixes and user experience improvements, so you are welcome to check it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-5767679488326961376?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/5767679488326961376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2009/12/odeo-new-release.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/5767679488326961376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/5767679488326961376'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2009/12/odeo-new-release.html' title='ODEO new release'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-9061217023971036438</id><published>2009-11-21T15:44:00.000-08:00</published><updated>2010-02-19T04:35:57.360-08:00</updated><title type='text'>HISE home page</title><content type='html'>Apache HISE has recenlty kickstarted and has a home page here: &lt;a href="http://incubator.apache.org/hise/index.html"&gt;http://incubator.apache.org/hise/index.html&lt;/a&gt;.&lt;br /&gt;Apache HISE is Human Interactions Service Engine. It's an open source implementation of WS HumanTask specification.HISE proposal can be found here &lt;a href="http://wiki.apache.org/incubator/HISEProposal"&gt;proposal&lt;/a&gt;.&lt;br /&gt;A voting took place on Apache ODE developer's list and resulted in voting for Apache HISE. You can find vote results here: &lt;a href="http://markmail.org/message/rtgiopf3o35a27sj"&gt;markmail&lt;/a&gt;.Apache HISE is looking for people interested in leveraging this project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-9061217023971036438?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/9061217023971036438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2009/11/hise-home-page.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/9061217023971036438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/9061217023971036438'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2009/11/hise-home-page.html' title='HISE home page'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-1954362066292349230</id><published>2009-11-12T01:04:00.000-08:00</published><updated>2009-11-12T01:04:02.592-08:00</updated><title type='text'>BPEL in Practice</title><content type='html'>I had a presentation on Warsaw JUG along with Maciej Próchniak.&lt;br /&gt;It was a brief overview of BPEL syntax and Apache ODE features.&lt;br /&gt;Maciej gave a good overview of SMX3 and SMX4.&lt;br /&gt;There are materials available to download (examples included). Details are &lt;a href="http://top.touk.pl/confluence/display/top/BPEL+in+Practice"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-1954362066292349230?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/1954362066292349230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2009/11/bpel-in-practice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/1954362066292349230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/1954362066292349230'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2009/11/bpel-in-practice.html' title='BPEL in Practice'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6983141563768732668.post-3587095004368622107</id><published>2009-11-07T21:42:00.000-08:00</published><updated>2009-11-07T21:55:12.048-08:00</updated><title type='text'>HISE</title><content type='html'>HISE stands for Human Interactions Service Engine.&lt;br /&gt;I have recently posted a &lt;a href="http://wiki.apache.org/incubator/HISEProposal"&gt;proposal&lt;/a&gt;, which was &lt;a href="http://markmail.org/message/rtgiopf3o35a27sj"&gt;accepted&lt;/a&gt; by Apache ODE PMC, which means the development will start soon.&lt;br /&gt;If you are interested in this project, you are welcome to join us.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6983141563768732668-3587095004368622107?l=rrusin.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rrusin.blogspot.com/feeds/3587095004368622107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://rrusin.blogspot.com/2009/11/hise.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3587095004368622107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6983141563768732668/posts/default/3587095004368622107'/><link rel='alternate' type='text/html' href='http://rrusin.blogspot.com/2009/11/hise.html' title='HISE'/><author><name>Rafał Rusin</name><uri>http://www.blogger.com/profile/09196932088834314947</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
