Welcome to Planet Eclipse

January 27, 2012

Ekkehard Gentz
Ekkehard Gentz

mobile development – my next sessions + events

here’s an overview of my upcoming sessions and events and I would be glad to meet you there:

M-Days – Frankfurt, 2012-02-01: Location Based Services

At the Mobile Days in Frankfurt I’m talking about Location Based Services. In many of my customer projects I’m using Location Based Services, have integrated Maps, track GPS etc. I’ll talk about good practices, tips and tricks and demonstrate some of my work. You’ll find me at Developer Stage 1 on Wednesday 2012-02-01 at 13:00.

In the night I’ll also attend the Mobile Media Night ;-)

At M-Days I’ll first time use my new Camholder from Heiko Behrens (@HBehrens) – will later blog about my experiences with heikos awesome new product.

BBDevCon Europe – Amsterdam, 2012-02-08: SuperApps

Only some days later I’ll speak at BlackBerry Developer Conference about developing Super Apps. I’m happy to meet some friends again and looking forward to get the newest informations about BB10 – the future OS for BlackBerry.

Mobile Developer Conference – HH, 2012-02-15: Push Services

More and more mobile applications are using Push Services. Unfortunately there’s no common API and so you have to know the differences and what’s possible on the different platforms. I’ll talk about PushServices for Apple, Google, Microsoft and RIM.

Mobile Tech Con 2012 – Munich 2012 – 2012-03-29: Power Workshop Cascades

Next MobileTechCon is in Munich – not far from Rosenheim, where I work and live. I’ll present a full-day Power Workshop about the new UI Framework Cascades from RIM. With Cascades you can write great apps in a short timeframe with awesome animations. Designers and Developers can work hand-in-hand: a PlugIn for Photoshop allows you to easy move graphical work and drag it into your QML Editor. Cascades is one of te reasons why I as a developer am sure, that RIM will came back in 2012. Using Cascades you can develop Applications for PlayBook 2.x and also upcoming BB10.

EclipseCon America 2012 :(

Unfortunately this time I cannot travel to EclipseCon America, because exactly same week there’s MobileTechCon in Munich.

But of course I’m developing the BlackBerry Conference App for EclipseCon 2012 and hope that the timing is better next year.

—————————————————————————————————————————

(c) 2012 Creative Commons License 3.0 (BY-NC-SA) by  ekkescorner 


Filed under: Blackberry, EclipseCon, mobile

Birt World
Birt World

BIRT Runtime Addition

As part of the 3.7 release BIRT now uses a BIRT POJO runtime. This change was described in the BIRT 3.7 New and Notable. If you are using a version of BIRT prior to 3.7 be sure to check out the Migration Guide. As part of the 3.7.2 release of BIRT which will be released in a couple of weeks, the team has decided to release a second runtime that uses the OSGi runtime. This new download will function similar to the BIRT runtime prior to BIRT 3.7 and is available on the full downloads page. You can try out the 3.7.2 release candidate version of this download by selecting the release candidate on the recent builds page.

Ian Skerrett
Ian Skerrett

Dev + Ops = Getting Software Deployed Faster (DevOps)

DevOps is one of those terms you hear a LOT about lately but I am not sure it is really well understood.  However, if you are going to be successful at Agile ALM it would seem natural you would want to bring the operations side of IT closer into the development process.   Puppet is one example of an open source project that is implementing some of the DevOps concepts.

When we put together the program committee for Agile ALM Connect we specifically wanted an expert from the DevOps community to make sure the program had a healthy devops slant.   Therefore, I was thrilled to have Lukes Kanies, the founder of Puppet and CEO of PuppetLabs, agree to be on the program committee and also speak at Agile ALM Connect on ‘what is devops’ and introduce Puppet.    We will also have Kenn Hussey talk about Geppetto, an Eclipse-based Puppet IDE.

In my Q&A series with Agile ALM Connect speakers, Luke answered three questions about DevOps.

1. ‘DevOps’ is a term that is used quite a bit lately.  How do you describe the term DevOps and why should developers care?

DevOps is in to operations what Agile is to development.  Operations needs to be a competitive advantage, adopting new technology quickly and with minimal business interruption, but in many cases the business goals have been lost and the new focus on policy and compliance has allowed IT to become a cost center.  DevOps is about operations teams working closely with everyone involved in product delivery to make sure that business needs come first.  This often involves a lot of automation, but the main thing is about making sure the customer comes first, just like in agile development.

Developers should care because organizations following devops practices will do a better job of supporting them, getting their software deployed faster and more easily.

2. You are the founder of the Puppet open source project.   Why did you start Puppet?
When I started Puppet, the tools and practices in IT had barely changed in ten years.  I was afraid that it would still not have changed in ten more years, and I saw an opportunity to build a better tool and help make the lives of sysadmins better.   Based on how passionate our user base, we seem to have struck a chord.

3. What advice do you have for people that want to learn how to use Puppet? 
First, start small, and fix the most painful things first.  Trying to boil the ocean by automating your whole infrastructure will just frustrate you and have little reward, but if you start by automating the small, menial work in your infrastructure you’ll have quick rewards and, even better, more time available in your day to work on the hard and important stuff.

 


Dave Carver
Dave Carver

Does Popularity = Success?

Does the current popularity of an open source project, automatically mean that it is successful?   It can but how do we define successful for an open source project?

Just because a project is popular does not necessarily mean that it is successful.  It just means at that point in time and duration it is also getting a lot of attention.   I’ve been involved with a wide variety of open source projects over the last 15 years.  Several I’ve started. Several I’ve participated in from both as a community member and as a committer.   Some I would say have been popular at one point or another, other’s I would say never hit the “High School” popularity meter thresh hold.

Popularity is defined by Merriam-Webster’s Learner’s dictionary as, “state of being liked, enjoyed, accepted, or done by a large number of people : the quality or state of being popular”.

Successful is defined as “having the correct or desired result.”   So being successful does not necessarily equal popularity.   A successful open source project is one that has met its desired goals and objectives.   One of them could be, to become popular, and blogged about, and tweeted about constantly, but the winds of popularity change at a moments notice.  Success lasts for as long as the project is meeting its stated goals.

Success is defined by the commiters and the community that forms around the project.  Is it meeting its user’s needs?  Is it growing its user community and committer base?  Is it adapting and changing to meet knew requirements?   These are just some of the criteria that a project can be measured on to be successful.  Yes, popularity can be one criteria, but it should not be the sole deciding factor.

We need to be careful on tying success to popularity alone.   There are many projects out there that I would consider successful that have never hit the popularity threshold.  Those projects may not be used by Millions of people, but they have built a community around their project, and provide value to that community.   How many people are using it, or number of companies that have adopted it, should not take away from the success of the project if it has met its objectives.

So success is going to mean different things to different people.  There is no one way to measure if project is successful.  To me, if your project even gets a handful of people forming a community around it, you are already successful.


January 26, 2012

Deepak Azad
Deepak Azad

Weird code pattern in Eclipse SDK

In recent Juno milestones JDT has added several new static analysis capabilities - resource leak detection (Juno M3), annotation based null analysis (Juno M4), null analysis for fields (Juno M5). This week I have been testing these new features on the entire Eclipse SDK source code. 

While there are quite a few 'gems', the following code pattern occurs quite frequently. If the object can be null at the first if condition, how is it magically guaranteed to be non-null at the second if statement?  :-)


As Stephan mentioned in his blog today - Help the JDT Compiler helping you. Please start using the new static analysis options and report any issues you find. In the process you will certainly make improvements to your code as well.

Eclipse Announcements
Eclipse Announcements

EclipseCon 2012 Gold Sponsors Announced

The Eclipse Foundation is pleased to announce the Gold sponsors for the upcoming EclipseCon 2012 conference in Reston, Virginia on March 26-29, 2012. Actuate, IBM, Oracle, Red Hat and SAP have all agreed to be the premier sponsors of the annual Eclipse community event.

Stephan Herrmann
Stephan Herrmann

Help the JDT Compiler helping you! - 1: Resource Leaks

During the Juno cycle a lot of work in the JDT has gone into more sophisticated static analysis, and some more is still in the pipe-line. I truly hope that once Juno is shipped this will help all JDT users to find more bugs immediately while still typing. However, early feedback regarding these features shows that users are starting to expect miracles from the analysis :)

On the one hand seeing this is flattering, but on the other hand it makes me think we should perhaps explain what exactly the analysis can see and what is beyond its vision. If you take a few minutes learning about the concepts behind the analysis you’ll not only understand its limitations, but more importantly you will learn how to write code that’s better readable - in this case for reading by the compiler. Saying: with only slightly rephrasing your programs you can help the compiler to better understand what’s going on, to the effect that the compiler can answer with much more useful error and warning messages.

Since there’s a lot of analysis in this JDT compiler I will address just one topic per blog post. This post goes to improvements in the detection of resource leaks.

Resource leaks - the basics

Right when everybody believed that Eclipse Indigo RC 4 was ready for the great release, another blocker bug was detected: a simple resource leak basically prevented Eclipse from launching on a typical Linux box if more than 1000 bundles are installed. Coincidentally, at the same time the JDT team was finishing up work on the new try-with-resources statement introduced in Java 7. So I was thinking: shouldn’t the compiler help users to migrate from notoriously brittle handling of resources to the new construct that was designed specifically to facilitate a safe style of working with resources?

What’s a resource?

So, how can the compiler know about resources? Following the try-with-resources concept, any instance of type java.lang.AutoCloseable is a resource. Simple, huh? In order to extend the analysis also to pre Java 7 code, we also consider java.io.Closeable (available since 1.5).

Resource life cycle

The expected life cycle of any resource is : allocate—use—close. Simple again.

From this we conclude the code pattern we have to look for: where does the code allocate a closeable and no call to close() is seen afterwards. Or perhaps a call is seen but not all execution paths will reach that call, etc.

Basic warnings

With Juno M3 we released a first analysis that could now tell you things like:

  • Resource leak: “input” is never closed
  • Resource leak: “input” is never closed at this location (if a method exit happens before reaching close())

If the problem occurs only on some execution paths the warnings are softened (saying “potential leak” etc.).

Good, but

Signal to noise - part 1

It turned out that the analysis was causing significant noise. How come? The concepts are so clear and all code that wouldn’t exhibit the simple allocate—use—close life cycle should indeed by revised, shouldn’t it?

In fact we found several patterns, where these warnings were indeed useless.

Resource-less resources

We learned that not every subtype of Closeable really represents a resource that needs leak prevention. How many times have you invoked close() on a StringWriter, e.g.? Just have a look at its implementation and you’ll see why this isn’t worth the effort. Are there more classes in this category?

Indeed we found a total of 7 classes in java.io that purely operate on Java objects without allocating any resources from the operating system:

  • StringReader
  • StringWriter
  • ByteArrayInputStream
  • ByteArrayOutputStream
  • CharArrayReader
  • CharArrayWriter
  • StringBufferInputStream

For none of these does it make sense to warn about missing close().

To account for these classes we simply added a white list: if a class is in the list suppress any warnings/errors. This white list consists of exactly those 7 classes listed above. Sub-classes of these classes are not considered.

Wrapper resources

Another group of classes implementing Closeable showed up, that are not strictly resources themselves. Think of BufferedInputStream! Does it need to be closed?

Well? What’s your answer? The correct answer is: it depends. A few examples:

1
2
3
4
5
6
7
8
	void wrappers(String content) throws IOException {
		Reader r1, r2, r3, r4;
		r1 = new BufferedReader(new FileReader("someFile"));
		r2 = new BufferedReader(new StringReader(content));
		r3 = new FileReader("somefile");
		r4 = new BufferedReader(r3);
		r3.close();
	}

How many leaks? With same added smartness the compiler will signal only one resource leak: on r1. All others are safe:

  • r2 is a wrapper for a resource-less closeable: no OS resources are ever allocated here.
  • r3 is explicitly closed
  • r4 is just a wrapper around r3 and since that is properly closed, r4 does not hold onto any OS resources at the end.
  • returning to r1, why is that a leak? It’s a wrapper, too, but now the underlying resource (a FileReader) is not directly closed so it’s the responsibility of the wrapper and can only be triggered by calling close() on the wrapper r1.

Summarizing: wrappers don’t directly hold an OS resource, but delegate to a next closeable. Depending on the nature and state of the nested closeable the wrapper may or may not be responsible for closing. In arbitrary chains of wrappers with a relevant resource at the bottom, closing any closeable in the chain (including the bottom) will suffice to release the single resource. If a wrapper chain is not properly closed the problem will be flagged against the outer-most wrapper, since calling close() at the wrapper will be delegated along all elements of the chain, which is the cleanest way of closing.

Also for wrappers the question arises: how does the compiler know? Again we set up a white list with all wrapper classes we found in the JRE: 20 classes in java.io, 12 in java.util.zip and 5 in other packages (the full lists are in TypeConstants.java, search for “_CLOSEABLES”).

Status and outlook

Yes, a leak can be a stop-ship problem.

Starting with Juno M3 we have basic analysis of resource leaks; starting with Juno M5 the analysis uses the two white lists mentioned above: resource-less closeables and resource wrappers. In real code this significantly reduces the number of false positives, which means: for the remaining warnings the signal-to-noise ratio is significantly better.

M5 will actually bring more improvements in this analysis, but that will be subject of a next post.

Chris Daniel
Chris Daniel

Fedora Eclipse Build: Introduction

It has been almost a month, since I stared my work for Red Hat.

I am taking care of Eclipse Build, which is even more complicated than regular Eclipse build (yes, Kim, that *is* possible).

The first and the most important assumption of Linux Eclipse Build is: no binaries allowed.

Some people call that kind of builds liberating. That is the last word that I'd use now ;-).

I will describe nuances that I have met during preparing Eclipse Juno for Fedora 17 in the following posts, but right now I'd like to mention just the first issue I have met:

If you want to build Eclipse, you need a builder, namely, a PDE Build. It looks like a chicken an egg problem, and the only solution is to build the builder using ant and OpenJDK. There is only one problem with that (OK, one serious problem and a lot of smaller ones that I will skip for now): Eclipse Java Compiler is not consistent with OpenJDK javac, or, stating it more clearly, JDT code cannot be compiled with javac.

That's not a big technical problem, as patching the source code before the build and making it javac compatible (and JDT incompatible) is not a very difficult thing, but it is open a rather serious question.

How does it come to the situation, where you cannot build Eclipse from scratch, but you have to use binaries to build Eclipse? Isn't it a bit against open-source philosophy? Today need we just Eclipse Compiler, which cannot be built (unless customized) from source. Tomorrow may we depend on something far less open.

Would not it make sense to put a requirement on Eclipse that some core plugins must compile with OpenJDK? I do not expect here mirroring all OpenJDK bugs in Eclipse compiler, but at least allowing for true open source build of it...

Here is a bug for those of you who are interested in the cause of the javac problem when building JDT.

In the next post: do Orbit users get what they expect?

EDIT: here is the link to the patch that makes JDT compile with OpenJDK.

Eclipse Announcements
Eclipse Announcements

Program Announced for the OMG/Eclipse Workshop

The Eclipse Foundation and OMG are pleased to announce the program for the third Eclipse/OMG Workshop on open specifications and open source software. The Workshop will occur on Sunday, March 25 in Reston, Virginia at the same location as EclipseCon 2012.

Lars Vogel
Lars Vogel

The end of Eclipse 3.x

Currently we have in my option the unfortunate situation that Eclipse did fork itself into a 3.x and 4.x stream.

Fortunately this is going to change.

I think it is worth to put emphasis on the statement of Mike Milinkovich.

Quote: As of the Juno release, Eclipse 4 is going to be the base platform for the Eclipse ecosystem. [SNIP] Eclipse 3.8 will also ship as part of the Juno release, but currently there are no 3.x releases planned after that..

I think its great the the platform gets ride of the two code lines.

For users this means that they should give the Eclipse 4.2 milestones a try. For Eclipse projects this means that they should test their plug-ins based on Eclipse 4.2.

For vogella.de this mean that I should update my Eclipse RCP tutorials.

Both should report bugs in case they find issues.

Happy bug hunting!

flattr this!

Tasktop Team
Tasktop Team

Why I joined Tasktop

I’ve long been an admirer of Tasktop, for a number of reasons: First, as Eclipse users already know, Tasktop has built some really cool Eclipse technology, including the Mylyn task-focused interface. But many companies have built cool open source tools. It’s much harder to take those tools and build a growing, dynamic company around them. But plenty of companies have also done that, usually by following the standard open source business model: package services and a bit of value-add around a captive open-source offering, and wait for customers. Tasktop takes a far more challenging and rewarding approach: It nurtures a healthy open source eco-system around core technologies, but then re-imagines and re-purposes them, leveraging unique products that address real customer pain. That takes real vision, and to me it’s a clear signal that the Tasktop leadership is able to imagine and execute at an entirely different energy level.

So rather than admire Tasktop from a distance, I joined it! I first worked with Tasktop last year as a consultant developing the initial implementation of what has become the Mylyn Model Focusing Tools project. That was a great opportunity to get to know some of the team and the Tasktop way. Everything I saw then fit nicely with what I’d already intuited. We have a really great combination of engineering excellence, creativity and lightweight organization.

It’s nice to say “we” again — I hadn’t realized just how much I’d missed having colleagues to work together with on challenging problems. The morning I joined Tasktop, I saw a stream of emails from everyone welcoming me to the team. I must admit to some cynicism about the whole “team” thing — like so much else, it can be an empty word that doesn’t match up to reality — but in this case it feels very genuine. So heartfelt thanks to everyone.

It’s an exciting time to be building software tools. It might sound funny, but I like to think of software development as a helping profession. That’s because I think that software products really can help people live more fulfilling, interesting and even happy lives. When I tell my family and non-techie friends that I’m working on Automated Lifecycle Management (ALM) tools I get a blank look. So instead I remind them that almost everything we do relies on software and that software programs are by far the the most complex artifact that humans have ever created. And I tell them that software development communities are growing ever more diverse, distributed, interwoven and complex. So what do we do at Tasktop? We build software that embraces those complexities.

Tasktop Dev tackles the issue of software complexity. It handles a lot of the repetitive and boring stuff, simplifies and clarifies everything else, and is deeply and imaginatively integrated with other development tools. Tasktop Sync and Code2Cloud — along with other exciting tools that we’re working on — tackle the even more challenging issue of community complexity. Even a relatively small software product might involve code developed by a rich community spanning companies, technologies, continents, and even (think about the Open-Source movement) different economic models and incentive systems. And in larger projects thousands of developers might be collaborating across all of these dimensions. Software development efforts are intimately connected with customers, management, marketing, support, regulators and every other imaginable kind of stakeholder. All of these people need to talk to one another, and it seems that everyone uses different tools to manage the unique aspects of their tasks or work environments. Tasktop builds software that helps those tools to work together so that everyone can focus together on the stuff that matters. In short, we break down boundaries and help people communicate. That’s worth doing.

January 25, 2012

Ralf Sternberg
Ralf Sternberg

Javascript validation with JSHint in Eclipse

Besides all the Java code in the RAP project, we also have more than 250 JavaScript files which total up to 75k lines of code. For such an amount of code, you should have some kind of code analysis that detects common coding problems like unintentional global variables. We use the JSEclipse plug-in for JavaScript editing which detects some, but not many JavaScript problems.

A while ago, we’ve tried to use JSLint, a tool written by JavaScript guru Douglas Crockford. Unfortunately, this tools produces several thousand warnings on our code base, many of them were not really problems but debatable coding style issues and there was no way to turn them off. JSLint’s lack of customizability recently lead to a fork named JSHint that is going to provide more flexible configuration options.

Like JSLint, JSHint is written in JavaScript, but can be run on the command line using tools like Rhino or JavaScriptCore. I tried JSHint on our codebase with good results using a shell script that runs it on top of Rhino. Unfortunately, checking all our 250+ *.js files keeps my machine busy for 5 minutes and 40 seconds and effectively turns it into a fan heater. This is not because JSHint itself is so demanding, but because for every file, a JVM has to be started, Rhino has to be loaded, then Rhino has to parse and load the JSHint JavaScript library, and then finally, jshint can parse and validate the source file.

Encouraged by the good results I tried to find a solution that doesn’t have this overhead. And as an Eclipse hacker and user, I certainly wanted to integrate the tool into my daily working environment. The result is a simple, yet efficient JSHint Eclipse integration that validates the same bunch of *.js files in less than 15 seconds.

jshint eclipse screenshot Javascript validation with JSHint in Eclipse

This speedup could be achieved by exploiting the way Eclipse builds projects: It uses the same builder instance to visit all files of the project recursively. That makes it possible to load and configure the JSHint library only once for the entire project and reuse it for all files being checked. Of course, validating all files of a project is only necessary for a full rebuild. During normal work, single files are being validated instantly when they have changed.

Although the configuration options are still somewhat basic, this integration proved to be very helpful already. I thought that it may be useful for others as well and decided to build and publish a first version. It’s available on the jshint-eclipse page. There’s an update site that let’s you install the plug-in right into your Eclipse IDE. If you find the plug-in useful, have ideas for improvements, find a problem or want to contribute, I’m happy to hear about it. To report problems, please use the github issue tracker.

Chris Aniszczyk
Chris Aniszczyk

Kepler

Just to let everyone know, some members of the eclipse.org community recently voted on naming the next simultaneous release after Juno gets released in June 2012. Taking input from the community, the Eclipse Planning Council finalized the name to be Kepler.

Personally, I think it’s a great choice and a nod to Johannes Kepler.

Blaise Doughan
Blaise Doughan

JAXB and Inhertiance - Using XmlAdapter

In previous posts I have covered how to map inheritance relationships in JAXB. This can be done by element name (via @XmlElementRef), by the xsi:type attribute, or in EclipseLink MOXy using another XML attribute (via @XmlDescriminatorNode/@XmlDescriminatorValue).  In this post the type indicator will be an XML attribute/element unique to that type, and we will leverage an XmlAdapter to implement this behaviour.

Read more »

January 24, 2012

Felipe Heidrich
Felipe Heidrich

How to load content in your IFRAME

When we started the TextView we used an IFRAME as the top most element.Over the time we changed the way we load the content of the IFRAME a few times, in this blog I will go over what we learnt in the process.
In our first version we made the entire initialization of the text view synchronous. That was done using this strategy:


var iframe = document.createElement("IFRAME");
parent.addChild(iframe);
var frameWindow = iframe.contentWindow;
var frameDocument = frameWindow.document;
var html = "<!DOCTYPE html><HTML><HEAD>";
for (var i = 0; i < stylesheets.length; i++) {
var objXml = new XMLHttpRequest();
objXml.open("GET", stylesheets[i], false);
objXml.send(null);
html += "<STYLE>" + objXml.responseText + '</STYLE>';
}
html += "</HEAD><BODY></BODY></HTML>";
frameDocument.open();
frameDocument.write(html);
frameDocument.close();
// call method to create all other elements
createElements(frameDocument.body);
This method works on all browsers but is not without limitations.
First, it is possible that iframe.contentWindow is undefined. This happens when the parent is not connected to the DOM.Another similar problem is that the parent (or an ancestor of it) can be hidden, in which case the browser can choose to notapply any styling to it.

The second problem is using STYLE instead of LINK to include the css files. In order to use STYLE we need to download all the filessynchronously one after the other. Another problem using STYLE is that all the URIs in the CSS are relative to the page base URI, which causes problemsduring deployment.

The solution for these problems is to wait for the load event of the iframe to write the html and to use LINK to include the css files:


var iframe = document.createElement("IFRAME");
var iframeLoaded = false;
iframe.addEventListener("load", function() {
if (iframeLoaded) return;
iframeLoaded = true;
var frameWindow = iframe.contentWindow;
var frameDocument = frameWindow.document;
var html = "<!DOCTYPE html><HTML><HEAD>";
for (var i = 0; i < stylesheets.length; i++) {
html += "<LINK rel='stylesheets' type='text/css' href='" + stylesheets[i] + "'></LINK>";
}
html += "</HEAD><BODY></BODY></HTML>";
frameDocument.open();
frameDocument.write(html);
frameDocument.close();
createElements(frameDocument.body); // BAD CSS is not done loading
}, false);
parent.addChild(iframe);
This code is step forward, it solves the problem when iframe.contentWindow is undefined.Using LINK also means that all files are downloaded in parallel and there is no problems with relatives URI inside the CSS.

The main problem with the code above is that the CSS are not loaded at the time body is being accessed. The solve this problem our initialsolution was to use the load event for the frameWindow:


var iframe = document.createElement("IFRAME");
var iframeLoaded = false;
iframe.addEventListener("load", function() {
if (iframeLoaded) return;
iframeLoaded = true;
var frameWindow = iframe.contentWindow;
var frameDocument = frameWindow.document;
var html = "<!DOCTYPE html><HTML><HEAD>";
for (var i = 0; i < stylesheets.length; i++) {
html += "<LINK rel='stylesheets' type='text/css' href='" + stylesheets[i] + "'></LINK>";
}
html += "</HEAD><BODY></BODY></HTML>";
frameDocument.open();
frameDocument.write(html);
frameDocument.close();
var windowLoaded = false;
frameWindow.addEventListener("load", function() {
if (windowLoaded) return;
windowLoaded = true;
createElements(frameDocument.body);
}, false);
}, false);
parent.addChild(iframe);
Here is where things get ugly, there are number of problems:

  • Firefox does not send any load events when document.write() is called from the iframe load handler.
  • calling document.write() not from the iframe load handler causes Firefox to change the navigation history.
  • Chrome some times does not fire load events for the iframe window (when navigating back or forward).
  • Safari sends the load event for the iframe before the CSS is loaded.
  • Webkit sends the load event for the iframe before the CSS is loaded, adding a SCRIPT element after the last LINK element fixes it for Webkit.
To workaround the problems listed above the next version includes a timer:


var iframe = document.createElement("IFRAME");
var iframeLoaded = false;
iframe.addEventListener("load", function() {
if (iframeLoaded) return;
iframeLoaded = true;
var frameWindow = iframe.contentWindow;
var frameDocument = frameWindow.document;
var html = "<!DOCTYPE html><HTML><HEAD>";
for (var i = 0; i < stylesheets.length; i++) {
html += "<LINK rel='stylesheets' type='text/css' href='" + stylesheets[i] + "'></LINK>";
}
html += "<SCRIPT>var waitForStyleSheets = true;</SCRIPT>";
html += "</HEAD><BODY></BODY></HTML>";
frameDocument.open();
frameDocument.write(html);
frameDocument.close();

var done = false;
frameWindow.addEventListener("load", function() {
if (done) return;
if (frameDocument.readyState === "complete") {
done = true;
createElements(frameDocument.body);
}
}, false);
var createTimer = function() {
if (done) return;
if (frameDocument.readyState === "complete") {
done = true;
createElements(frameDocument.body);
} else {
setTimeout(createTimer, 10);
}
}
setTimeout(createTimer, 10);
}, false);
parent.addChild(iframe);
The version above is almost our current solution. Except that it does not work on Firefox. For some reason, on Firefox the frameDocument.readyState stays permanently set to "interactive" when document.write() is called from the iframe load handler. The only way we found to detected that all CSS are loaded was checking the cssRules of each stylesheet (thank you Mihai).


var iframe = document.createElement("IFRAME");
var iframeLoaded = false;
iframe.addEventListener("load", function() {
if (iframeLoaded) return;
iframeLoaded = true;
var frameWindow = iframe.contentWindow;
var frameDocument = frameWindow.document;
var html = "<!DOCTYPE html><HTML><HEAD>";
for (var i = 0; i < stylesheets.length; i++) {
html += "<LINK rel='stylesheets' type='text/css' href='" + stylesheets[i] + "'></LINK>";
}
html += "<SCRIPT>var waitForStyleSheets = true;</SCRIPT>";
html += "</HEAD><BODY></BODY></HTML>";
frameDocument.open();
frameDocument.write(html);
frameDocument.close();

var done = false;
frameWindow.addEventListener("load", function() {
if (done) return;
if (frameDocument.readyState === "complete") {
done = true;
createElements(frameDocument.body);
}
}, false);
var createTimer = function() {
if (done) return;
var ready = false;
if (frameDocument.readyState === "complete") {
ready = true;
} else if (frameDocument.readyState === "interactive" && isFirefox) {
var sheets = frameDocument.styleSheets;
if (sheets.length === stylesheets.length) {
var index = 0;
while (index < sheets.length) {
var count = 0;
try {
count = styleSheets.item(index).cssRules.length;
} catch (ex) {
//invalid access error means the css is not loaded
if (ex.code !== DOMException.INVALID_ACCESS_ERR) {
//other errors, like network security, assume the css is loaded
count = 1;
}
}
if (count === 0) { break; }
index++;
}
ready = index === sheets.length;
}
}
if (ready) {
done = true;
createElements(frameDocument.body);
} else {
setTimeout(createTimer, 10);
}
}
setTimeout(createTimer, 10);
}, false);
parent.addChild(iframe);

This is all the code that was needed to load the content into the iframe - somewhat extreme if you'd ask me. Probably the most pertinent question is why we are using an iframe, the answer to that is definitely another post...

Felipe Heidrich
Felipe Heidrich

Using the Orion Editor with Almond

In my last post I gave instruction how to use the Orion Editor without requirejs, since then the code changed quite a bit and the instructions in the last post no longer work. We changed all the editor files to follow the AMD spec (you can find more details about this change here). It is still possible to use the editor without requirejs but you will need to use an AMD "shim" loader. The one I recommend is almond.

To illustrate how to use the editor with almond I decided to write an simple application for that. It is actually an upgrade of the code snippet written by Andrew Niefer in this post. You can find my version of the code in gist.

Besides changing the snippet to use requirejs I have also added a few extra features.

Here are the instructions:

First, in your blog post add a pre element with the attribute name set to "orion".
Then, in the class attribute you can specify the following parameters:

  • writable - if set the element is writable.
  • ruler - if set the line numbering ruler is shown.
  • js - use the javascript syntax highlight styler.
  • java - use the java syntax highlight styler.
  • css - use the css syntax highlight styler.
  • html - use the html syntax highlight styler.
Last, at the end of your blog added these lines:

<script src="http://planetorion.org/editor/orionformatterbuilt.js"></script>
<script type="text/javascript">
require("examples/textview/orionformatter");
</script>
Here is an example:

<pre name="orion" class="js ruler writable">
var this = "is some javascript code";
</pre>
This gets rendered to:

var this = "is some javascript code";
Now that the introduction part is over I'd like to talk about the process I used to create the orionformatterbuilt.js file which is the compiled version of orionformatter.js.

First lets take a look at what a html page with requirejs needs to do use orionformatter.js:


<!DOCTYPE html>
<html>
<head>
<script data-main="orionformatter" src="../../requirejs/require.js"></script>
<script type="text/javascript">
require({
baseUrl: '../..'
});
</script>
</head>
<body>
<h3>Orion Text View Demo: using Orion Formatter and RequireJS</h3>
<pre name="orion" class="js writable ruler" style="border: 1px solid teal;">
/* Some js code */
function log (text) {
var console = window.document.getElementById('console');
showConsole();
}
</pre>
</body>
</html>
It only needs to include "requirejs/require.js" and point data-main="orionformatter", very clean. The second script element setting the baseUrl was just necessary because our directory structure is a bit different.

The next step is to replace requirejs by almond.


<!DOCTYPE html>
<html>
<head>
<script src="/examples/textview/almond.js"></script>
<script src="/examples/textview/orionformatterbuilt.js"></script>
<script src="/examples/textview/orionformatter.js"></script>
<script src="/orion/textview/eventTarget.js"></script>
<script src="/orion/textview/textModel.js"></script>
<script src="/orion/textview/keyBinding.js"></script>
<script src="/orion/textview/textView.js"></script>
<script src="/orion/textview/projectionTextModel.js"></script>
<script src="/orion/textview/tooltip.js"></script>
<script src="/orion/textview/rulers.js"></script>
<script src="/orion/editor/regex.js"></script>
<script src="/orion/editor/textMateStyler.js"></script>
<script src="/orion/editor/htmlGrammar.js"></script>
<script src="/orion/textview/annotations.js"></script>
<script src="/examples/textview/textStyler.js"></script>
<script type="text/javascript">
function onload() {
require("examples/textview/orionformatter");
}
</script>
</head>
<body onload="onload();">

<h3>Orion Text View Demo: using Orion Formatter and Almond</h3>

<pre name="orion" class="js writable ruler" style="border: 1px solid teal;">
/* Some js code */
function log (text) {
var console = window.document.getElementById('console');
showConsole();
}
</pre>

</body>
</html>
Note that to use almond directly it was needed to include all the required files manually. Another difference is that requirejs ensures that orionformatter only runs when the dom is ready. With almond we don't get that, that is why the load event handler was necessary.

Now is the time to run the requirejs optimizer on almond. This is the magic:

$ node r-edge.js -o baseUrl=../.. name=examples/textview/almond include=examples/textview/orionformatter.js out=orionformatterbuilt.js uglify.ascii_only=true

Notes:

  • uglify.ascii_only=true was needed because textView uses unicode characters
  • r-edge.js was used because of a bug in r.js, this will soon be fixed.
  • See orionformatter.js line 16, without this line almond did not work (for me).
  • The doc suggests to pass wrap=true to the optimizer, in this case that can't be used as the load event handler needs to call the require method.
Now using orionformatterbuilt.js the html above can be simplified to this:

<!DOCTYPE html>
<html>
<head>
<script src="orionformatterbuilt.js"></script>
<script type="text/javascript">
function onload() {
require("examples/textview/orionformatter");
}
</script>
</head>
<body onload="onload();">

<h3>Orion Text View Demo: using Orion Formatter and Almond (optimized version)</h3>

<pre name="orion" class="js writable ruler" style="border: 1px solid teal;">
/* Some js code */
function log (text) {
var console = window.document.getElementById('console');
showConsole();
}
</pre>

</body>
</html>
In some cases, like when using the Orion Formatter with Blogger, it might not be possible to add a load event handler to the body. The workaround is add the script elements at the end of the body. The html would look like this:

<!DOCTYPE html>
<html>
<body>

<h3>Orion Text View Demo: using Orion Formatter and Almond (final version)</h3>

<pre name="orion" class="js writable ruler" style="border: 1px solid teal;">
/* Some js code */
function log (text) {
var console = window.document.getElementById('console');
showConsole();
}
</pre>


<script src="orionformatterbuilt.js"></script>
<script type="text/javascript">
require("examples/textview/orionformatter");
</script>
</body>
</html>

Ian Skerrett
Ian Skerrett

Integrating Lifecycle Tools with OSLC and Eclipse Lyo

Lifecycle tool integration is a key issue for the new breed of tools emerging around the concepts of Agile ALM.   Eclipse is a great platform for tools integration on the desktop but how do tools integrate on the server?   OSLC and Eclipse Lyo are a specification and open source implementation for solving lifecycle tools integration.

Michael Fiedler and Steve Speicher will be talking about OSLC and Eclipse Lyo at the upcoming Agile ALM Connect conference.    To introduce people to the Agile ALM Connect speakers and topics, I will be doing a short Q&A with some of the speakers.    Below Michael and Steve provide some background on OSLC and Eclipse Lyo.

1. What is OSLC and why does the industry need OSLC?

OSLC (Open Services for Lifecycle Integration) is an open community dedicated to reducing barriers for lifecycle tool integration.   The community authors scenarios and specifications for exposing application lifecycle data (change requests, test cases, requirements, etc) through uniform interfaces which rely on the architecture of the World Wide Web and Linked Data standards.

Organizations use a variety of lifecycle tools – commercial, open source and those developed in house – which need to share data, resources and assets.  Current integration approaches are often based on fragile and proprietary point-to-point APIs.   Tools adopting OSLC can interoperate easily using a linked data approach which enables loosely-coupled integrations with improved quality, navigation and traceability of shared data.

2. How would you like people or companies to contribute to the Eclipse Lyo project?

Individuals and companies are welcome to participate in both the Eclipse Lyo project and in the OSLC workgroups.   The Lyo project is looking for developers interested in promoting OSLC adoption by developing SDKs, reference implementations, compliance tests and examples.   OSLC workgroups develop integration scenarios and specifications to address different aspects of the system and software lifecycle (requirements, development, test, etc).   Workgroup participation is open and is a great way to learn more about OSLC and contribute to new and evolving specifications.

3. What is the best resource to start using OSLC and Eclipse Lyo?

Getting started with Eclipse Lyo and OSLC is easy.  To get started with Lyo, visit the Wiki on eclipse.org (http://wiki.eclipse.org/Lyo) to get an overview of the project.  To participate in Lyo development, you can start by introducing yourself on the development mailing list, lyo-dev@eclipse.org.  To participate in OSLC, visit http://open-services.net/participate and  join in the discussions on the forums, mailing lists and workgroup meetings.


Wayne Beaton
Wayne Beaton

Top Ten Ways to Say Eclipse

Every couple of days, I get an email from somebody looking for a price quote for Eclipse. Generally, the sender is a software reseller acting on behalf of a client. Sometimes they ask to partner with us, sometimes they just want a simple price quote. In all cases, I answer with some boilerplate text that I keep around:

Eclipse is free and open source software that is distributed royalty-free under the terms of the Eclipse Software User Agreement. Please let me know if we can be of further assistance.

Now, the interesting thing for me, is the number of different product names people use to describe the thing that they want to buy. Here are a few of my favourites (in no particular order).

  • Eclipse Foundation Eclipse Galileo SR1 3.5.1 EN 01
  • IDE License JAVA programming: Open Source
  • The “Eclipse” Software
  • “For a Better World” (an Eclipse Publication)
  • LTO Ultrium 5 1500 GB Data Cartridges
  • Eclipse Indigo (3.7) Packages for Mac OS
  • Eclipse + plug-in
  • ECLIPSE IDE for Java EE Developers 1.2.0.20090621-0820 epp.package.jee for Win7
  • ECLIPSE Practice Management Software/Medical Billing Software
  • SCA dev lab Software and SCA tools

There’s a couple in there that seem to come out of nowhere, obviously from folks who have us confused with somebody else. Curiously, I get almost no email about soccer clubs or vampires.

EclipseCon 2012AGILEALM 2012


Ian Skerrett
Ian Skerrett

Final Week for Eclipse Award Nominations

This is the final week of nominations for the Eclipse Community Awards.   I would particularly like to see more nominees in the Top Committer, Top Contributor and Newcomer Evangelist category.    Deadline for nominations is Friday, January 27, 2012.


Thomas Kratz
Thomas Kratz

Richt Text Editor for Eclipse/SWT

I have been looking around, but a feasible Rich Text Editor for SWT seems to be hard to find. I finally came accross the FCKEditor integration from the JFire/Nightlabs guys. They do not promote it, but it works fine for me. I had to grab some dependencies from different repos at nightlabs and make some hacks to make it play nice with the Rest of my app, but it looks stable and works on all platforms (some other editor needs a xulrunner, thats still messy on 64bit platforms) as it uses the Browser widget to render FCKEditor.


Customized FCKEditor in an eclipse e4 RCP app.

EclipseLive
EclipseLive

Upcoming Event: Webinar: Transforming development visibility and productivity with Borland StarTeam 12.0 and Tasktop

Event Date: February 7, 2012 8:00 am GMT-8

Register Now

Mik Kersten, Founder of Eclipse Mylyn, CEO Tasktop Technologies & Stuart McGill, Borland General Manager
 
Abstract:
StarTeam 12 is here with full Tasktop Dev and Sync support. The new StarTeam release, together with Tasktop, includes a host of new features designed to benefit both developers and management. Now it is easier than ever to extend the interoperability and co-existence between ALM tools and asset types across software development teams, while management benefit from improved insight into delivery goals and their predictability. In this webinar you will discover the benefits of our new collaboration, and: * Discover how StarTeam customers benefit from Borland's strategic partnership with Tasktop * Learn how Tasktop Sync delivers visibility by integrating StarTeam with your other ALM tools * See how developers get the most modern and integrated experience for StarTeam with Tasktop Dev
delicious delicious | digg digg | dzone dzone

Eclipse Jetty
Eclipse Jetty

i-jetty 3.1 Released

Release 3.1 of i-jetty for Android is now available from the Android Market and the i-jetty download page.

This release updates the embedded Jetty to jetty-7.6.0.RC4, although the majority of the changes have been to the Console, which is a webapp that allows you to interact with your Android device from a remote browser.

Higlights include:

  • pagination of large data sets such as Contacts and Media thumbnails (images, videos)
  • re-implementation of generated content as json & ajax REST
  • ability to cause the device to ring (helpful for finding it around the house!)
  • ability to show current location of the Android device on Google maps , or track its location on the map as the device moves.

Here’s a screenshot showing tracking my phone as it moves from the Sydney Opera House to Fort Denison on Sydney Harbour:

Tracking phone via i-jetty console webapp

Tracking phone via i-jetty console webapp

Enjoy.

January 23, 2012

Peter Kriens
Peter Kriens

Objects Revisited

Alan Kay is the  inventor of Smalltalk, the first fully truly object oriented language. I learned Smalltalk in the early eighties and almost everyday that I use Java I am crunching my teeth that James Gosling did not steal more ideas from Smalltalk. About 20 years ago, during an OOPSLA, Alan Kay presented the idea that data should always carry its own methods to access that data. His example was

Holger Staudacher
Holger Staudacher

An OSGi JAX-RS connector Part 1: Publishing REST services

In a recent blog post Peter Kriens commented that the OSGi service model is as important as object-orientation. I feel the same – I don’t want to write software without this concept anymore. But for me, the service model only makes sense when it’s used together with the modularity OSGi provides. I think the modularisation layer is the greatest advantage of the OSGi platform and the services are really only there to simplify the communication between modules.

When it comes to developing a REST API with Java, this advantage is missing in most of today’s libraries (e.g. Restlet or Jersey), because the Java language still lacks modularity. But especially for the design of a REST API this concept can be a great benefit, because it overcomes the limitation of only being able to separate REST services by url and Java packages. With modularity the service implementations can be separated into modules which improves the maintainability and the beauty of the whole system a lot.

A few months ago I discovered JAX-RS for developing REST services. (Before that I used Restlet.) I have to say that the JAX-RS API makes it really easy to develop REST services. See this article for a how-to. A reference implementation of this API is Jersey. The cool thing about this implementation is that it plays really well together with the OSGi HttpService and it ships as bundles. In this way we have the option to actively deploy REST services into the HttpService. But is this how we want to publish REST services? To me, it’s not!

In my ideal world I would write my @Path annotated Pojos and publish them as OSGi services. That’s it. The runtime should take care of publishing and service wiring. Sadly, Jersey has no built-in feature for that. This is the reason I wrote a little OSGi-JAX-RS connector. The only thing the connector does is that it publishes OSGi services as REST services using JAX-RS. Of course, there are OSGi remote services, but using them does not allow the use of JAX-RS the way I’d prefer, namely as a lightweight additional bundle.

You can find the connector in GitHub. To make it work simply install it into your OSGi instance by using this jar. (You’ll also find a p2 repository there). That’s it. The only thing you have to take care of is writing the REST services like the one in this example.

@Path( "/osgi-jax-rs" )
public class ExampleService {
 
  @GET
  public String seyHello() {
    return "JAX-RS and OSGi are a lovely couple.";
  }
}

The activator can then look like this:

public class Activator implements BundleActivator {
 
  private ServiceRegistration<?> registration;
 
  @Override
  public void start( BundleContext context ) throws Exception {
    ExampleService exampleService = new ExampleService();
    registration = context.registerService( ExampleService.class.getName(), exampleService, null );
  }
 
  @Override
  public void stop( BundleContext context ) throws Exception {
    registration.unregister();
  }
}

Further instructions can be found in the README of the git repository. It also contains two examples for using this connector with and without declarative services. In the second part of this blog series I will show you how to configure the services using the OSGi Configuration Admin Service and publish services on different ports within the same OSGi instance. I hope you enjoy this connector as much as I do.

followme An OSGi JAX RS connector Part 1: Publishing REST services

January 21, 2012

Gunnar Wagenknecht
Gunnar Wagenknecht

Use Target Definition Files in PDE Build

I’m not hip when it comes to building Eclipse based products. I still use plain vanilla PDE Build. The cool guys all switched to Tycho. Well, you’re allowed to call me dinosaur then. Anyway, I’ve been using .target files as a source for dependency management for quite a while now. They are very useful in Eclipse. All dependencies for all the bundles are defined in one place. You simply open one and Eclipse starts downloading one half of the Internet. Maven already did the other half, I’ve heard.

I also use them to drive PDE Build. Instead of specifying stuff to fetch for a build again I simply point PDE Build to the same .target file I use in the IDE. Works like a charm as long as you only use “Software Sites” (p2 repositories) which are accessible via URL by any developers Eclipse instance as well as the build machine.

Previously, this was implemented by transforming the .target file XML using XSL into an Ant script. The Ant script did a bunch of p2 mirror calls to download the bytes. I recently upgrade to a newer version of the builder containing a Juno version of the org.eclipse.pde.core bundle. Starting with 3.8 this bundle defines a nice Ant task that does not require the XSLT magic.

<target name="buildTargetPlatform" unless="skipTargetDefinition">
  <!-- note: this requires pde.core (from Juno) in the base builder -->
  <pde.provisionTargetDefinition
      targetFile="/path/to/my.target"
      destinationDirectory="${repoBaseLocation}/target"
      clearDestination="false"/>
</target>

January 20, 2012

Michael Jastram
Michael Jastram

ProR Snapshot Build available

Good news to everyone interested in ProR - we finally have a snapshot build available on the RMF website.  If you are interested in ProR, ReqIF, etc., please give it a spin.

The last release took place in August 2011 - an eternity ago, as far as software is concerned.  The reason for this long delay had been announced before: We migrated ProR to Eclipse, where it became the GUI for the Requirements Modeling Framework (RMF).  Becoming an Eclipse Foundation process is a huge endeavor: A project has to undergo a comprehensive intellectual property review, and once migrated, there are strict rules to ensure that all IP is accounted for.  As if this is not enough, we also performed some major refactoring of the code base.

Read the rest at the Formal Mind Blog

BJ Hargrave
BJ Hargrave

Juke Box Hero, Got Stars In His Eyes


I learned Wednesday that I was named a JavaOne Rock Star for my Why OSGi? presentation with Peter Kriens at JavaOne 2011. Nice!

Jae Gangemi
Jae Gangemi

happy 2012

greetings and salutations in the year 2012! after a very, very long hiatus, development work on perlipse has resumed.

stay tuned for further updates!

Laurent Goubet
Laurent Goubet

Traceability test case : UML to Java generation

The next version of Acceleo will introduce a number of improvements of its existing features, one of its most important, the automatic builder, being entirely re-written in order to get rid of legacy code and improve the user experience. This also comes with a much better experience for users that need to build their Acceleo generators in standalone, through maven or tycho. More news on this are available on the bugzilla and Stephane's latest post.

One of the least visible features, yet one I find among the most interesting aspects of the Acceleo code generator, is the traceability between the generated code, the model used as input of the generation, and the generator itself. Basically, you always know where that esoteric line of code came from : which part of the generation template generated it, and which model element triggered its generation.

This feature has known a series of improvements as we used it intensively with the UML to java generator. We are now confident that we can record and display accurate information even for some of the most complex use cases. This generator isn't the most complex generator we could write with Acceleo, but it is quite complete nonetheless. Here are some examples of what the Traceability can provide to architects developping their code generators :

Determine which model element triggered the generation of a line of code


On the left-hand side, a file that has been generated. On the right-hand side, an editor opened as result of using the action "open input" : the model is opened and the exact element that was used to generate the part of code is selected.

Find the part of a generator that created a given part of the code

On the left-hand side, the same generated file as above. On the right-hand side, the result of using the "open generator" action : the Acceleo generator which generated that selected part of the code is opened, with the exact source expression selected.

Real-time Synchronization



These are but a few of the features that can be derived from the synchronization between code, model, and generators. Some more examples include : previewing the result of a re-generation, incremental generation, round-trip (updating the input model according to manual changes in the output generated code)...

Most of these features are better seen in video to get an idea. If you want to see some of them in action, some more flash videos of what traceability can do for you are available on the Obeo network (though a free registration is required).

Andrei Loskutov
Andrei Loskutov

Eclipse job in Böblingen

We (Verigy) have a job opening for a Java / Eclipse developer in Böblingen / Germany. Details on G+.

Gunnar Wagenknecht
Gunnar Wagenknecht

Upcoming Events

I know some of you already finished planning for the next few months. There are a couple of interesting events I’ll attend which might be of interest for you. Thus, I thought sharing won’t hurt.

FOSDEM (Feb. 4 – 5, Brussels, Belgium)

I’ve never been in Brussels before. I’ve also never been at FOSDEM before. Andrew told me about his plan to generate some nice Eclipse buzz there. Well, it looks like that will turn out great. Mike will be there too. We’ll have an Eclipse stand for people to show some projects and talks about Eclipse and we’ll also give a few talks about Eclipse. Mine will be about EclipseRT.

EclipseCon (March 26 – 29, Reston, Virginia, USA)

Ok, this one is a classic (for me). I’ve been there before. You gotta have to be there! However, this year my flight to EclipseCon will be shorter. The event moved from the west coast to the east coast. Frankly, I always wondered about switching location away from Santa Clara. But I’ll also miss San Francisco. It’s a beautiful city always worth a visit. Yet it took me three EclipseCons until I finally visited it in 2009 for the first time. I may need to find a new event in that area. ;)  Anyway, I’ll give one of the many tutorials there (Dynamic Server Applications with EclipseRT).

JAX (April 16-20, Mainz, Germany)

Also bit of a classic, I like that event. It’s packed with lots of sessions and people. I’ll talk about developing cloud applications with Eclipse Gyrex. Our first major version (1.0) is only weeks away and that talk will be a great opportunity to learn more about Gyrex and see how we use it to solve some interesting problems.

Hope to see you soon at any of the events!

Jan Kohnlein
Jan Kohnlein

Multitouch Gestures in the Generic Graph View

In my previous post, I've already described the discovery mechanisms of the Generic Graphical View project: Starting from one node you can step by step reveal other connected nodes in the same model. The model itself is fixed - it is still a view! - but the user can decide herself which subset of elements should appear in the diagram. That behavor allows to create diagram views focussed on a specific semantic aspect of the model.

The challenge is to find a decent UI for nodes wich have several hidden connections. How should a user select any subset of these?

Since the Helios release SWT supports four multitouch gestures: PAN, ZOOM, SWIPE and ROTATE. On my Mac's touchpad these gestures are actually easier to perform than a conventional drag operation because there is no extra mouse button. So I decided to give it a try and have a look how gestures could be used in the graph view. Here is a screencast showing the results:



SWT's multitouch API is fairly simple (example snippet). The first step was to add multitouch events to GEF, such that the can be handled in the same way as mouse or keyboard events. I had to extend a couple of GEF classes. If you're interested in the details, have a look at the classes in the package org.eclipse.xtext.graphview.behavior.gestures and the GraphViewRootEditPart.

These changes allow to use a ZOOM gesture on a ScalableFreeformRootEditPart.
Note that the PAN gesture is already supported by GEF because the FigureCanvas uses hardware scrolling. Unfortunately, these event is always consumed, such that it will not make it through to other GEF elements.

The ZOOM gesture can also be used to drill down into elements. If the mapping defines an open reference to another diagram, you can drill down by selecting it and performing the ZOOM in gesture. If you‘re inside a drill down diagram, you can ZOOM out into the container diagram.

Any Tool can now handle multitouch gestures by implementing the IViewerGestureHandler interface. For a DragTracker this makes no sense, as it is exited as soon as the mouse key is released and you cannot start a drag and a multitouch gesture simultaneously.

The RevealGestureTool works as follows: Click on the + button to reveal the hidden connected elements, Then use ROTATE or SWIPE to rotate elements, ZOOM to change the distance and right-click to select and pin individual elements. Another click will commit the input.

January 19, 2012

Mariot Chauvin
Mariot Chauvin

Modeling 2.0 : Let's collaborate!


A bit of history



4 years ago, when I joined Obeo, I started to work on a new modeling tool dedicated to system engineering. The main focus of this tool was to enable system engineers to model graphically complex systems with different representations, for each speciality, depending on their viewpoint. The tool was associated to a methodology and integrated in a modeling workbench.




Separation of concerns by representations was a first step to scalability of graphical representations, another was to add several mechanisms (layers, filters, hide/reveal) to allow end users to hide some elements. The approach is somehow similar on what Miles is working on.

We took the decision to create a generic runtime with the possibility to specify graphical representations and to drive the tooling by the viewpoints. The approach has similarities with Jan current's work, and I think our work inspired him a little bit.

Since the runtime has been used for safety analysis (diagram screenshot) and several other use cases.

However, although our tool primary concerns was collaborate modeling since its inception, we did not offer directly a solution to the concurrent access problem. In fact, we left it to the Revision Control System (RCS) used by end users. As Alex wrote concurrent access management by RCS have several drawbacks, so we decided to offer the possibility for end users to collaborate more seamlessly.

On the technical side, we decided to use CDO, a technology we had experienced successfully in others projects, and which seems to match the most to our requirements. As our graphical modeling technology is based on GMF Runtime, our global technical task was to integrate GMF and CDO.

GMF and CDO, integration challenges


If you are used to component architecture like the Eclipse platform one, you may think that these two components will plug together quite easily. Unfortunately, this is not the case for various reasons :

  • EMF Transactions and CDO Transactions
    GMF Runtime relies on EMF Transaction to manage read and write accesses to models. To simplify this means that one is not allowed to do a modification without encapsulating its change in a recording command. On its side CDO provides its own transaction mechanism, which relies on the database store one. So it is necessary to integrate the two mechanisms. This is one of the features Dawn provides (see those bugzilla entries for further information).
  • Transactional model break in GMF Runtime
    GMF Runtime is a bridge between EMF models and GEF. Among others things, it provides a notation model, to store graphical information. The synchronization between the graphical model and the semantic model, is one of the responsibility of edit parts. The choice to split the synchronization responsibility in each edit part enables one to easily override the default behavior for a given edit part. This choice is consistent with the high extensible approach of the framework. However, it has one major drawback, edit parts should be instantiated to update the notation model ! As GMF Runtime edit parts creation is done in an post commit listener, when no models changes are allowed, the runtime have to force the transaction using a special option.
    This behavior prevents one to have triggers for those modifications. If you need to avoid conflicts (see below), you will not be able to acquire lock before commit. In this case it means that one have to extract the synchronization from edit parts and to call it at the right time.
  • Avoiding conflicts
    If CDO provides live updates of shared models, it does not prevents conflicts. There is two ways to handle them. The first one is to write your own conflict resolver, which will take a decision when a conflict occurs. The second one is to avoid conflicts through locks. Easier to said than to implement, but that the way we choose.
    • Lock integration
      To avoid conflicts, the simplest way is to lock automatically elements before their edition. In practice, one could use the EMF Transaction trigger mechanism to do this. Edit parts need to listen to locks events to deactivate accordingly their edition capabilities and provide visual indicators of the lock. Lastly, to provide logical lock for end-users, one may provide a lock strategy.
    • Consistency maintenance on client side
      EMF Transaction enables one to rollback a transaction, before its commit. This is generally done for validation or lock acquisitions purposes. The recording command manages this rollback and will abort properly the transaction if it occurs. However with the abort, the CDO state of the object will change (see bug 312534 for more details). To avoid conflicts a solution is to use CDO save points to restore the object to a clean state if a transaction aborts.
       
  • Native mode for GMF Runtime notation models ?
    One of the coolest thing of CDO is its EObject implementation, but to benefit from the scalability it provides, you need to regenerate your metamodel with a CDO dependency. When one works with such CDO model instances, the mode in which one is, is called native. As GMF Runtime notation metamodel depends on the EMF one (don't do this at home), using notation models in native mode is far from being easy. So we worked on a solution which keeps source and binary compatibility with legacy code (see bug 336707 for technical details) and provides notation cdo native models, the code is available here (no builds yet).
       
  • Content and cross reference adapters
    These two utilities should not be used as they will break the lazy loading mechanism of CDO. By default GMF runtime initializes one cross reference adapter when configuring the editing domain. You could quite easily override the default behavior. EMF Transaction uses an adapter that walk through its content, but removing it is much harder. 
On our product, the work is still in progress, but we he have implemented solutions for most challenges presented above. During this work we opened several issues :   
As you may seen, the CDO team has been very responsive, and already provided fixes for most of them. I would like to thank them for their availability and help.

This blog entry present results coming from a work collaboration between Thales and Obeo.
Ce message de blog est issu d'un travail en commun entre Thales et Obeo.

EclipseLive
EclipseLive

P4Eclipse Tutorial

Perforce Software
 
Abstract:
See how to install, configure, and use P4Eclipse, the Perforce Plug-in for Eclipse. Connect to a Java project in a workspace. Edit, diff, and submit a file. Perform a refactor and use graphical tools to review file history. (10:20 mins.)
delicious delicious | digg digg | dzone dzone

EclipseLive
EclipseLive

Modernize your ALM Architecture with Tasktop Sync 2.0

Dr. Mik Kersten, Tasktop CEO, Founder of Eclipse Mylyn
 
Abstract:
In this must-see webinar, Tasktop CEO Mik Kersten will provide the first in-depth view of Tasktop Sync 2.0. Tasktop Sync 2.0 provides a set of industry-first facilities for connecting your ALM stack. With the massive response to Tasktop Sync 1.0, we have focused this release on features for capturing your ALM architecture in the Sync tool in order to connect all stakeholders with real-time traceability and collaboration. Our goal is to help you transform your ALM stack by allowing you to tailor the best of open source, Agile, in-house, and enterprise ALM solutions. 
delicious delicious | digg digg | dzone dzone

Eclipse Announcements
Eclipse Announcements

Last Week of Nominations for The Eclipse Community Awards 2012

The nomination deadline for the Eclipse Community Awards is January 27, 2012. Don't forget to nominate the individuals or products that were the best in 2011. Winners will be announce at EclipseCon 2012.

Roy Ganor
Roy Ganor

Getting Started with Facebook App Development

Last week I was playing with Facebook App development, getting ready to the Facebook announcement. It was quite pleasant experience, although things could be simpler. The Facebook Open Graph concept gives a nice overview on what and why this all about, so that part went very smooth. When things get technical, the Facebook Developers site turns messy. That is, all topics are covered in a 'tutorial' approach rather than an API approach like most developers are used to. Moreover, the layout of this page is definitely not intuitive as it mixes between reference and tutorial docs. That's said, the general experience was good.

To help other developers get started with Facebook app development I created a nice application which take the reader through the steps to develop applications with phpcloud.com. It was a nice exercise and it can really help with the development workflow.

The topic "Getting Started with Your Facebook App on phpcloud.com" covers :

  1. Create an account on phpcloud.com
  2. Create an app on Facebook
  3. Setting up development environment
  4. Deploy a sample Facebook app to phpcloud.com
  5. Push updates to your Facebook app


January 18, 2012

Vojimir Golem
Vojimir Golem

Getting started with PlayN (Part II)

Part I has shown how to install and use the PlayN a cross-platform game abstraction library. In this screencast you will see how to use Eclipse IDE to run/edit/debug cross-platform games developed with PlayN.

This short (4 minutes) screencast shows the same "Showcase example" presented at Google I/O 2011: "Kick-ass Game Programming with Google Web Toolkit" by Ray Cromwell and Philip Rogers.

In this video more emphasis are put on tool (Eclipse & PlayN) usage:







Hudson-CI Blog
Hudson-CI Blog

First Hudson Release from Eclipse Foundation

The Hudson team is pleased to announce its 3.0.0 Milestone 0 release from the Eclipse Foundation. We have worked diligently and expertly over the past year to get to this milestone release.  Since release 1.398  the Hudson community has benefited from the team’s work through the introduction of the 6-week release cycle, based on a new development and release process and the ongoing work on bugs, enhancements and new features

What is included in this release?

The M0 release is the first release of Hudson as a top level technology project from the Eclipse Foundation. It has been a very busy 12 months for us and that is shown in the large numbers of new features, enhancements and bug fixes the team has developed.

Over 50+ new features and enhancements cover:

  • Maven 3
  • Cascading Projects
  • JAXB-based REST API and plugin,
  • enhancements to
    • Parameterized Builds
    • Downstream Projects
    • User Management
    • Security and Authorization
    • UI
    • GIT support

Over 350 bugs across the full range of Hudson have been fixed especially focused on stability, performance and the core SCM plugins such as GIT and SVN.

In parallel to this, in August 2011 the team began the process of submitting the Hudson core code to the Eclipse Foundation  The foundation has stringent entry requirements on all project source code and third party licences to ensure they are IP and license clean. Hudson’s source code, split over 10 core modules, has now been approved and is available in the Eclipse GIT repository.

There are over 200 third party libraries distributed with Hudson (including many that relate only to plugins).  Some of these are LGPL licensed libraries that the Eclipse Foundation does not accept under any circumstances. The team developed and implemented a strategy to replace these with more suitable libraries ensuring little impact on the core code or Hudson plugins using them.

For example:

  • The Java Native Access, JCaptcha and JFreechart  libraries have been repackaged as external plugins for this release. Additionally HawtJNI will be bundled as part of Hudson core for future releases, to replace the JNA support.
  • The BIRT Charting engine will be the charting method of choice going forward, but backward compatibility with JFreechart is maintained by existing plugins through the simple addition of a dependency on the external JFreechart libary package.
  • Winstone, originally used as the the standalone container for Hudson has been replaced by Jetty.

The balance of the libraries were considered for submission to the IP checking process.  In itself this is no small task. Each library has to be submitted with its source code.  Some of the libraries were so old that the code was not readily available or had been forked with local changes.

The Hudson team modernized the code through such means as replacing forked libraries with current versions and working with library owners to feed forked changes back into the latest library versions.  The Eclipse Foundation contacts owners and contributors to libraries to establish IP cleanliness.

As you can imagine, this is a labour intensive process but the work of both the Hudson team and library owners has ensured that over half of the 100+ third party libraries have been approved already. This core set of 100+ libraries represents those that are physically packaged in the core war.

The rationalization and approval process for the balance of the libraries is ongoing. But the result of this mammoth effort is that Hudson is ready to move forward and develop features related to the high level themes that the community agreed upon.

The final part of the effort in the leadup to this M0 release is the work that has been done on both the Hudson Eclipse website and wiki. Much of the content from the older hudson-ci.org has been rewritten or updated and moved to the new infrastructure. Over 70 pages are now available from the new sites, including the recently published Hudson Book (151 pages of material in it’s own right) that contains the most up to date information on installing, administering and using Hudson.

What can you contribute to this release?

As an alpha release we are not expecting miracles! But the release has gone through development and testing cycles and we are very pleased with the results.  You should be able to run this release of Hudson on your container of choice and expect it to behave well. You can install plugins  and expect them to run.

With the changes to libraries detailed above there may be some issues that we need to address quickly. Known issues will be with any plugin that uses JFreechart. We are in the process of either forking or contacting plugin owners to create the dependency on the external plugin. But the plugin may not yet be available from the update center. Keep an eye on the blog and Twitter feed for the latest news.

If you have any issues or further enhancements relating to this Eclipse release Please raise issues in the Eclipse Bugzilla system which you can find at https://bugs.eclipse.org/bugs/ - Hudson lives under the top level Eclipse Technology project. You will need to register for an Eclipse BugZilla account to log issues if you don’t already have one. For more information on the Hudson community, mailing lists, forums etc. please head over to the communities page.

Feel free to join us at the next community phone call to voice your opinions and experiences with this new release.

What is coming next?

It’s our intention to release monthly milestones until we get to our first approved Eclipse production release. By which time we feel that the Hudson project at Eclipse will be fully functional and ready for migration of your production servers. In the meantime, updates will continue in parallel on hudson-ci.org for all your production Hudson needs.

Susan Duncan


Eric Rizzo
Eric Rizzo

Today is "strike" day to protest SOPA

Today is "strike against censorship" day to protest the SOPA and PIPA bills that are attempting to pass in the US Congress. Please educate yourself about the potential negative impacts of these laws and get involved.

http://sopastrike.com/strike
https://www.google.com/landing/takeaction/
http://americancensorship.org/


Jan Kohnlein
Jan Kohnlein

Discovery Diagrams for the Generic Graphical View

If you've read my previous posts or seen my presentation at EclipseCon Europe 2011, you'll already know the Generic Graphical View framework: Using two Xtext-based DSLs - one for mapping semantic to graphical elements and the other for styling the figures - you can easily create nice looking diagrams for any Java based model.


In its first version the contents of the diagram was entirely defined in the mapping DSL. It was only possible to restrict the visible elements to a subset of the model by adding filtering expressions in the mapping. For bigger models it was hard to focus on a subset that is not structural defined but based on semantics, e.g. all classes that deal with addresses in a CRM application.

Many graphical frameworks handle the selection of the visible elements in a diagram by means of dialogs. The user is then forced to switch between keyboard and mouse which is annoying, and these dialogs are often complicated and unintuitive. The goal for the Generic Graph View project was to build a UI for choosing the diagram contents that uses the mouse or trackpad only and avoid dialogs at all cost. The following screencast demonstrates the basic functionality.



As a first step, actions were introduced that allow to hide existing graphical elements - nodes, labels or connections. If you hover over an element, you'll get an popup button allowing to remove it from the view. So you can start with a big diagram and strip it down to what you want to see. Once an element inside a node has been removed, you can restore the node completely using another popup button. You can define elements as initially hidden using a hidden flag in the mapping definition.

In addition to the subtractive approach, you can step by step extend the diagram contents from an initial node. If you're hovering over a node that has hidden connection, several + buttons will popup. When one of these buttons is triggered, the hidden elements and connections will appear in transparent arranged in a circle around the source element. In the same drag operation you can change the distance and the angle of that circle. This behavior will get really cool with multitouch gestures, which I will cover in a separate post.

Stephane Begaudeau
Stephane Begaudeau

Maven integration in Acceleo

With the release of the new Acceleo stand alone front end for the compilation of Acceleo modules, I’ve started to work on a brand new maven integration in Acceleo.

Currently in Acceleo, if you need to build Acceleo modules with maven you have to use a Tycho based build with a java class generated by Acceleo to tweak the build (for example to register the metamodel(s) used in the modules). This Tycho based build will always produce an Eclipse plugin as a result.

The next major release of Acceleo will have a maven plugin dedicated to the compilation and it will bring several key improvements. Firstly, the new compilation front end brings a completely stand alone compilation. Those who want to build their Acceleo modules without having to build an Eclipse plugin will be able to do so. Secondly, this new front end support more complex project structures (with for example, multiple output folders in a same project). Thirdly, you will have the ability to contribute a class to influence the uris of the dependencies in the saved files (for example, change all the uris of the dependencies to other module to “platform:/plugins” uris that are more “eclipse plugin” friendly). Finally, it also features an improved resolution of the dependencies of a project with several options.

Your project will be able to have a dependency to Acceleo modules in another project (that should have been previously compiled). A valid Acceleo project is just a directory on the file system with at least one “source” sub-directory and one “output” sub-directory (no need of an Eclipse nature or anything like that).

This first solution is fine as long as you have the source code of the other modules but sometime you need to build something with the dependencies in jars. The maven plugin for Acceleo will let you declare a dependency to a jar containing already compiled Acceleo modules by using:

  • The absolute path of the jar. Ex: C:\…\myJar.jar
  • The path of the jar relative to the project built. Ex: ${project.basedir}\lib\myJar.jar
  • The groupId and the artifactId of the jar resolved by maven  (the version of the jar is optional since some version number includes the date of the build and therefore change often). Ex: myGroupId:myJar:myVersion
  • The name of an Eclipse bundle resolved by Tycho preceding by “p2.eclipse-plugin” only in a Tycho based build (“p2.eclipse-plugin” is the groupId of all the dependencies resolved by Tycho). Just like the previous use case, the version of the jar is optional too. Ex: p2.eclipse-plugin:myJar:myVersion

For those who want to have a look at this new maven based build for Acceleo, you can find its source code on github.com and you can test it with a simple pom.xml like this one.

Mik Kersten
Mik Kersten

Happy Birthday Tasktop

Five years ago, on Friday January 15th, I defended my PhD thesis on Focusing Knowledge Work with Task Context. The following Monday, January 17th, we incorporated Tasktop Technologies. Driven by the years of research that it took to prove that tasks are more important than files, integration is more important than features, and that focus begets flow, we embarked on a journey to bring to market a transformation in how we work and collaborate around software.

Our journey and passion have been fueled by our customers and our open source community, as to date we have not taken any external funding, and instead embarked on what’s more recently been defined as the Lean Startup approach to building a company in an Agile and customer-centric fashion. Bootstrapping, we have doubled in revenue and nearly doubled in head count each year since our inception, and now support over a thousand customers and over a million open source users. Working closely with our ISV partners, the Eclipse community and open source ALM projects, we are proud to be one of the key contributors defining the future of ALM.

In addition to the opportunity to be a part of a transformative endeavor, what’s guided our vision is a manic focus on the needs of individual software workers. Mylyn and its commercial counterpart, Tasktop Dev, materialized because the growth in complexity of software and the fragmentation of ALM tools were bringing our and our fellow developers’ productivity to a halt. Tasktop Sync was born out of the same need to give other stakeholders such as testers, project managers and business analysts, a connected and collaborative view on the software delivery process. With our focus on integration, our goal is to empower developers and other stakeholders in order to advance ALM to support the rise of the software-powered economy.

We want to take this birthday moment to thank all of the customers and partners who have made it possible for us to do what we love, which is to invent the future of ALM and to strive for our goal of doubling the productivity of software developers and managers. We hope you like the next round of innovations that we are hard at work for launching in 2012, which will be a definitive year for software, for ALM and for Tasktop Technologies.

January 17, 2012

Kim Moir
Kim Moir

2011 by the numbers

2011 was an exciting year in the Eclipse community.  From my corner of the Eclipse universe, he's what it looked like:


One book chapter, many thanks



I contributed a chapter on Eclipse to the Architecture of Open Source Applications in 2010 and the book was published in May 2011.  Thanks to Amy Brown and Greg Wilson, for their long hours editing and providing feedback to the authors of this book.  It's a great read!  When Greg first approached me about writing this chapter, my immediate thought was "How hard could it be? I live and breathe Eclipse all day".  It was much more difficult that I imagined but in the process I learned a tremendous amount and am a better committer for the experience.  Many thanks to DJ Houghton and John Arthorne for reviewing my drafts and providing valuable feedback. A special thanks to Jeff McAffer who I interviewed about the decision to switch to OSGi in 3.0 and Steve Northover for his suggestions to make the SWT section into something more pixel perfect.  Merci Olivier Thomann for answering my many compiler questions,  and Boris Bokowski and Paul Webster for their thorough discussions with me regarding the modelled workbench and dependency injection in 4.x.  Also, thanks to Mike Wilson to allow me the flexibility in my job to spend some time at work working on this chapter.  I'm excited to see that Amy and Greg are now editing a second volume of this book.

Six milestones, many release candidates, two service releases, and one coordinated release, four streams, thousands of builds, millions of tests
No rest for the committers.

143 bug fixes
I closed about 143 bugs in the releng bucket in the past year.  That doesn't seem like much really.  I'd have liked to solve more.  The largest issues implemented from a releng perspective were shared licenses, code coverage, and the largest work item, the Git migration.

42 Git repos 
The Equinox and Eclipse projects migrated all their repos to Git.  We now have about 42 Git repos.  This involved a tremendous amount of work on the part of the Eclipse team as a whole.  There were many whiteboard drawings and detailed discussions about the migration process with John, Paul and a Mr. Gheorghe.  There was no Ringo.  Thank you Paul for all the huge amount of testing, script writing, and migration of all the ui and e4 repos. Thanks John for your work many sage suggestions on our Git migration, as well as your suggestion to implement the git flow method to simplify our development and build processes.  Thanks Andrew Niefer for migrating many of the Equinox and PDE repos, Bogdan Gheorghe for your work with SWT, and Oliver Thomann for testing JDT Core repos.  Thanks Tom Watson for your Git advice, having already climbed the Git learning curve while working on the OSGi Alliance repositories.  To Dani Megert and Markus Keller, your always fine attention to detail and pointing out areas that could be improved is appreciated. Paul is giving a talk about our migration at EclipseCon 2012 called Let's Git this Party Started.  I'm sure it will be insightful and entertaining.

One EclipseCon, two talks, one castle, many great people
I was privileged to attend EclipseCon Europe in Ludwidsberg this past November and present two talks.  I thoroughly enjoyed preparing these talks, and even more presenting them.  On the Wednesday morning, I talked about our Git Migration, and that evening I gave a talk with John Kellerman about history of Eclipse over the past 10 years.  After the second talk, a few people came up to me and said that the talk was so good that it should have been a keynote.  That was very fantastic to hear because we really put a huge amount of effort into that presentation.  I also had a lot of fun talking to people at our booth where we had posted many pictures of the Eclipse family from over the years. The Saturday after the conference Simon Kaegi, Eric Moffatt and I visited Heidelberg castle.  Canada scores very low on the castle index so this was a treat.   


You can't buy Eclipse magazines or giant pretzels at train stations in Canada either. I was impressed.



19 blog posts
I didn't have much time to write blogs posts this year.  The most popular one I wrote this year was about smashing open source stereotypes.




I'm never sure how popular a blog post will when I write them. It's always a surprise.  The comparison of Mozilla and Eclipse build infrastructure I wrote last year still holds the record for most popular (it ended up on reddit).


One marathon, many kilometers of training
How is running related to release engineering?  Running keeps me sane when release engineering gets crazy :-)  Preparing for the Ottawa marathon in May means that you have to start training at the end of January.  Running through snow, ice, wind and rain teaches you there isn't really anything you can't do when you are willing put in a lot of hard work to reach your goal.  And when you reach that goal, there's a lot of joy, because you know that you have conquered all the obstacles in your path and emerged victorious.

My sneakers after a 19K training run through deep slush
Open source is really a huge team effort and I had a lot of fun in the Eclipse community in 2011.

Who knows what 2012 will bring?

Kai Toedter
Kai Toedter

Eclipse 4.x talk for JUG Ostfalen

If you are interested in the Eclipse 4.x Application Platform and happen to live close to Braunschweig (Germany), join my talk for the JUG-Ostfalen:

Was ist neu bei der Eclipse Rich Client Platform 4.x?

When: Friday, January 20th, 7:00 pm
Where: CKC Braunschweig, Am Alten Bahnhof 13, 38122 Braunschweig
Language: German

After my session there is another talk: “Agile Review” (Eclipse Plugin) by
Malte Brunnlieb, Philipp Diebold, Thilo Rauch und Peter Reuter.

The event is free: Registration and info is here: http://eclipse4.eventbrite.com/

Would be great to see you there!

Kai

You find me on Twitter and Google+.
Next Eclipse RCP 3.x/4.x trainings in Munich

flattr this!

Holger Staudacher
Holger Staudacher

Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse

As you might know from previous posts, most of my work time has something to do with the development of REST based systems. The systems we develop are mostly written in Java. To ensure that a system works, we have a step in our continuous integration process that executes integration tests before automated deployment is launched. With this short post I’d like to show you our setup for these integration tests because when I searched a few months ago the results were rare.

We write integration tests for REST systems with JUnit and restfuse. Check this post for a how-to on restfuse. Thanks to the Maven surefire plugin we can simply execute these tests in our maven build. Here is the build and dependency section of the test module’s pom.

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.9</version>
      <executions>
        <execution>
          <id>test</id>
          <phase>test</phase>
          <configuration>
            <testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
          </configuration>
          <goals>
            <goal>test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    ...
  </plugins>
</build>
 
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.8.1</version>
    <scope>test</scope>
  </dependency>  
  <dependency>
    <groupId>com.restfuse</groupId>
    <artifactId>com.eclipsesource.restfuse</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

Most of our Java-REST applications ship as war files.  So, at this stage the question becomes, “How can I test the war file I just built?” One answer is to hot deploy the war file and run the tests against it. But, for a hot deployment we need a server running tomcat (or another servlet container), right? Actually, we don’t icon wink Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse . We can simply embed a Jetty plugin into our maven build, start it and deploy our war file using the Maven Jetty plugin. The related section in the pom looks like this:

<build>
  <plugins>
    ...
    <plugin>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>maven-jetty-plugin</artifactId>
      <version>${jetty-version}</version>
      <configuration>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <stopKey>foo</stopKey>
        <stopPort>9090</stopPort>
        <contextPath>/</contextPath>
        <tmpDirectory>/tmp/work/</tmpDirectory>
        <webApp>/tmp/test.war</webApp>
        <daemon>true</daemon>
        <reload>manual</reload>
      </configuration>
      <executions>
        <execution>
          <id>start-jetty</id>
          <phase>test-compile</phase>
          <goals>
            <goal>deploy-war</goal>
          </goals>
        </execution>
        <execution>
          <id>stop-jetty</id>
          <phase>verify</phase>
          <goals>
            <goal>stop</goal>
          </goals>
        </execution>
      </executions>
    </plugin>  
    ...    
  </plugins>
</build>

It is important that we deploy the war file before the actual test phase, in our example, during test-compile. To make this work we need to copy the new war file into the configured directory before we run the maven build. This can be accomplished with a simple shell script.  The following snippet shows how it looked for our jenkins job:

rm -rf /tmp/work
mkdir /tmp/work
cp $WORKSPACE/../job/**/*.war /tmp/test.war

A few last points.  In our setup we split the integration test build from the main build but you can merge them together as well. And, when using restfuse an important thing to keep in mind is that you need to configure the port to be the same as the one jetty uses to run the tests.

That’s it – short but efficient. Maybe you have a similar approach to share in a comment with us?

followme Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse

Ankur Sharma
Ankur Sharma

OSGi Tracing in Equinox

The Equinox implementation of OSGi provides the tracing APIs in org.eclipse.osgi plug-in since Eclipse 3.5. The tracing options are generally Boolean flags stored in a .options file as key-value pair. A typical .options file would look like this

org.my.plugin/ui=true
org.my.plugin/ui/editor=true
org.my.plugin/ui/prefs=true
org.my.plugin/debug=false
org.my.plugin/debug/data=true

The hierarchy is defined using the slashes. But this is only a general practice. The tracing does not understand this.

-osgi.debug
To load the values from the .options file, provide the file name as command line parameter (or program parameter in launch config)

command line arg example
eclipse.exe -debug C:\tracing\.options

program argument (in launch config) example
-Dosgi.debug=C:\tracing\.options

Using -debug is same as setting the osgi.debug system property.

Accessing the option values at runtime
1. In RCP application
If the RCP application has access to the org.eclipse.core,runtime.Platform object and thus they can access it directly like this

String value = Platform.getDebugOption("org.my.plugin/ui");

User can validate if the program is running in debug mode using Platform.inDebugMode() API.

2. In pure OSGi application
An OSGi application can access these options using the DebugOptions service


ServiceTracker debugTracker = new ServiceTracker(bundleContext, DebugOptions.class.getName(), null);
debugTracker.open();
DebugOptions debugOptions = (DebugOptions) debugTracker.getService()
boolean uiOption = debugOptions.getBooleanOption("org.my.plugin/ui", false);

Using the API has the advantage that user does not have to check for nullness.

More Tracing API
org.eclipse.osgi provides more APIs which are very helpful in logging the trace.

1. Registering a debug option listener
The listener can be registered as service using the BundleContext (that you receive in the activator class when the bundle is started)


final Hashtable<String, String> properties = new Hashtable<String, String>(4);
properties.put(DebugOptions.LISTENER_SYMBOLICNAME, TracingConstants.BUNDLE_ID);
bundleContext.registerService(DebugOptionsListener.class.getName(), new MyDebugOptionsListener(), properties );

2. Listening to the debug option change events
Once the listener is registered, a callback will happen each time a debug option is changed. The callback does not tells you the delta and instead throws the whole lot. So we can use this place to read and init from the DebugOptions


/* (non-Javadoc)
* @see org.eclipse.osgi.service.debug.DebugOptionsListener#optionsChanged(org.eclipse.osgi.service.debug.DebugOptions)
*/
public void optionsChanged(final DebugOptions options) {
//DebugTrace trace;
trace = options.newDebugTrace("org.my.plugin");
// boolean field
DEBUG = options.getBooleanOption("org.my.plugin/debug", false);
}

this is just an indicative code. You don't have to necessarily do it this way.

3. Writing to trace
This is the easiest part. Afterall the reason we did the whole exercise was to make the tracing simple. A handle to trace object can be obtained from the debug options.


/** Trace object for this bundle */
private final static DebugTrace TRACE = MyPluginActivator.getDefault().getTrace();  // returns the trace object obtained using options.newDebugTrace("org.my.plugin");




@Override
protected Control createContents(final Composite parent) {
if (MyPluginActivator.DEBUG) {
TRACE.traceEntry("/debug", parent);
}
...
...
}

Checking MyPluginActivator.DEBUG is optional. TRACE.traceEntry will check for the flag "/debug" anyway. This is to improve of the performance. We store the the flag values to boolean fields and update them through the listener.



4. Where is the log file?
 The log is stored in the file as set in the debug options. By default, it tends to store them to workspace\.metadata\trace.log

options.setFile(new File("/path/to/trace/file"));

5. Controlling the trace logs
The logs are conntolled by two system properties

eclipse.trace.size.max : The system property used to specify size a trace file can grow before it is rotated
eclipse.trace.backup.max : The system property used to specify the maximum number of backup trace files to use

Easier way to manager the logs?
PDE will be providing UI for managing the logs and make them dynamic. See Bug 296631. This is mostly like to make it to Juno M5 release.

What do you mean by dynamic?
If you notice, the debug options can be loaded at the launch time (using -osgi.debug) or programatically when running. However, if you wish to turn the tracing on/off in a running product, its tricky. PDE will be providing an extension using which a plug-in can expose its debug option flags. The UI will display these flags in preferences where they can be turned on/off for a running application. Cool! isn't it?


* If you find any discrepancies in the above post, please bring it to my notice so that they can be updated.

Update: Tracing UI is now available in latest Integration builds and will be there from Juno M5.

January 16, 2012

Tom Schindl
Tom Schindl

SVG for FXML-Conversion

So some weeks ago I read Jasper Potts blog on FXG to FXML-Conversion tool (useing simple XSL-Stylesheet). This blog Jasper asked if there’s probably one day someone providing a conversion tool for SVG.

This has been on my list for some time now and because I was traveling a bit in the last 2 weeks I had some time to hack on such a converter. I’ve not used XSL but instead used xtend (svg-parser (java),fxml-converter (xtend)) (because an XML-File comes with a lot of multiline strings). It took some time to wrap my head around SVG and how I could translate this in FXML/JavaFX 2.0 API calls but I finally I’m at a point where I have something to show off:

Please note that the JavaFX 2.0 image on the left is only made up of primitive JavaFX 2.0 elements (Circles, SVGPaths, Rect, Gradients, …) and it by far does not yet handle all the nifty stuff one can do with SVG but it shows me that such a conversion tool is doable to some extend though e.g. when it comes to filtering, … SVG has much more definitions than the JavaFX-API currently provides.

I was not even able to convert the SVG-Gaussian-Blur to JavaFX’ Gaussian-Blur (but that might just me I’m not an expert in graphics stuff), SVG allows to apply multiple filters/effects to a node, … . So to provide full SVG-Support – without residing to libraries like Batik – in JavaFX 2.x we’d need more API (or at least a tutorial how to e.g. write custom effects) but even with the current API one can get quite far as you don’t notice any missing thing in the above screenshot.

I’ve pushed the orignal svg-File (from the KDE oxygen-theme) and the resulting fxml-File to my git repo so that you can compare them.


Orion
Orion

Writing a Content Assist Plugin For Orion

Orion includes a simple but powerful infrastructure for implementing content assist for your favorite language. This article will describe how to create your own content assist plugin by working through a simple example. As with any Orion plugin, the starting point is an HTML file declaring your plugin. You can find a complete example here, but the body of the plugin is a simple script like this:

  window.onload = function() {
    var provider = new eclipse.PluginProvider();
    provider.registerServiceProvider("orion.edit.contentAssist",
      new RubyContentAssistProvider(),
      {name: "Ruby content assist", pattern: "\\.(ru|rb)$"});
    provider.connect();
  };

This script registers an implementation of the orion.edit.contentAssist service. The service parameters indicate that it should be associated with filenames ending in “.ru”, or “.rb”. The content assist implementation is found in the RubyContentAssistProvider object defined in a separate script, rubyContentAssist.js. This script defines a service implementation object declaring the computeProposals method. The completion reference for the arguments and return value of this method are provided in the orion.edit.contentAssist documentation.

Example 1: Simple keywords

Let’s start with a simple example that offers completion on a subset of Ruby’s reserved keywords.

function computeProposals(prefix) {
  return ["alias","and","begin", "break","case","class"];
}

We are given a string argument that contains the sequence of word characters immediately preceding the current cursor position. We didn’t use the argument here but we could have used it to only compute the proposals matching that prefix. Since a simple keyword list is trivial to compute we didn’t bother – the Orion content assist implementation will only show proposals matching that prefix anyway. Here’s a shot of our current content assist implementation in action:

Example 2: Advanced completion features

Now let’s look at a more interesting example:

  function computeProposals(prefix, buffer, selection) {
    var proposals = ["alias","and","begin", "break","case","class"];
    var prefixStart = selection.offset - prefix.length;
    var precedingChar = buffer.charAt(prefixStart - 1);
    if (precedingChar === '=' && "begin".indexOf(prefix) === 0) {
      //suggest writing a block comment
      proposals.push({
        proposal: "begin\n\n=end",
        description: "=begin - block comment",
        escapePosition: prefixStart+6
      });
    }
    return proposals;
  }

We have added two more arguments to the computeProposals function: buffer, and selection. These arguments contain the current editor buffer and selection at the time content assist was invoked. We are using this information to check if the user is attempting to create a Ruby block comment, which starts with “=begin”.

Instead of returning a simple string in this example, we are returning a proposal object. This object allows us to provide more details back to the caller such as a description of the proposal, and the cursor position the editor should have after the completion has been inserted. In this case we want the cursor to end up inside the newly created block comment.

Also note that the text of the proposal does not include the equals character. The completion engine will only replace the provided prefix word, which only includes normal word characters (letters, numbers, or the underscore character). We already know that the character immediately before the prefix is an equals character already, so we don’t need to insert another one. Here is a shot of our enhanced content assist in action:

Note that both the begin keyword and the block comment proposal are included here. The description we provided for the block comment proposal helps the user understand the difference in this case. A more complete example could do more sophisticated analysis of the source to rule out the possibility of a keyword appearing at this location, and only show the block comment proposal.

Example 3: Linked mode completion

We’ll use one final example to illustrate Orion’s linked mode completion. This works exactly like some of the content assist in the Eclipse Java development tools, where after selecting a proposal the user uses the tab key to iterate through a set of fields that need to be filled in. Once all the fields are filled in, the user presses enter to finish the insertion process and exit linked mode. In Orion we indicate a linked mode completion by adding a positions property to a returned proposal. This property is an array of position objects indicating the offset and length of each linked region that requires user completion. In this example we use linked mode for an “if block” template where the user must provide the conditional expression:

  function computeProposals(prefix, buffer, selection) {
    var proposals = [];
    var prefixStart = selection.offset - prefix.length;
    if ("if".indexOf(prefix) === 0) {
      //suggest writing a block comment
      proposals.push({
        proposal: "if condition\n\t\nend",
        description: "if - if block",
        positions: [{offset: prefixStart + 3, length: 9}]
        escapePosition: prefixStart+14
      });
    }
    return proposals;
  }

When this proposal is accepted, the proposal text is inserted and the editor selection moves to the first position, which is the “condition” field. Below is a screenshot of what the editor looks like after this proposal has been selected. Note that the message area in the Orion toolbar indicates to the user that they have entered into a linked mode completion.

After editing the condition, the user hits Enter to finish the insertion, and the cursor will move to the indicated escape position. Note that the escapePosition property doesn’t need to account for the fact that the user might add or remove characters in the linked fields before they are done. The content assist engine will automatically adjust this value to account for any typing, so you just need to record the final cursor position under the assumption that the user will not modify any of the linked fields.

This concludes our overview of Orion’s content assist infrastructure. As these examples illustrate, it is very easy to get started with writing your own content assist service for Orion. Writing a truly powerful content assist service requires much more in depth source code analysis, but Orion takes care of all the basic editing infrastructure to let you focus on the language analysis. Check out the complete Ruby editor example and Developer guide for the most up to date details.


Kai Toedter
Kai Toedter

GWT Contacts Demo with MVP and Testing

On Monday, January 23th, I am going to talk about some cool features of the Google Web Toolkit (GWT) at the OOP 2012 conference in Munich. To have a live demo for discussion, I implemented a GWT port of my Eclipse 4 Contacts Demo. In this blog post, I talk a bit about my experience with Google’s MVP (Model View Presenter) approach, including activities, places and event bus. Furthermore about UIBinder in combination with GWT Designer and Presenter testing using Mockito.

You can find the latest source of the demo at https://github.com/toedter/gwt-mvp-contacts. Here is a screen shot, as you see, I did not focus on nice design. Click on the image to see it in original size.

Model View Presenter (MVP)

The Model View Presenter Pattern has different flavors: “Passive View” and “Supervising controller“. In Passive View there is no dependency between model and view, Supervising Controller is not so strict and allows e.g. data binding from model to view. In GWT, presenters are represented by Activities, views are implemented by GWT UI classes. There are 2 common ways to define the binding between views and presenters: Either the presenter defines a display interface that the view has to implement, or the view interface provides a presenter interface. The latter one is often used in GWT when the UI is created with UIBinder, because it makes it easier for the view to call back to his presenter. In the contacts demo, the view interface for the list view looks like

public interface IContactListView extends IsWidget, AcceptsOneWidget {
  public interface Presenter {
    void goTo(Place place);
    void select(int index);
    void select(Contact contact);
  }

  void setPresenter(Presenter presenter);
  void selectInitialContact(Contact contact);
  void initialize(List contacts);
}

As you see, for laziness reasons I don’t use “Passive View” since I pass a domain object (Contact) to the view. A good introduction into GWT MVP you find at the GWT Web site. If you have a more application-like layout with kind of toolbar and several display regions, you might think you will need nested presenters/activities, but you don’t have to nest them. Thomas Broyer wrote a nice article about this issue, and I used his approach in my demo.

UIBinder and GWT Designer

UIBinder splits a UI component into a Java part and an XML/CSS part. That makes it easier to separate concerns and helps designers and developers working together. GWT Designer is a nice and free GWT UI Editor for Eclipse. One feature is the automatic creation of MPV related infrastructure, like corresponding activities and places. In the demo I have several implementations of the list view and the details view. You can change them by altering the ClientFactory implementation. The screen shot below shows a small details view example in GWT Designer, klick on it to see the image in original size.

Presenter Testing with mockito

One advantage of MVP based approaches is the good testability. For that purpose I wrote a few exemplary tests using mockito as Mocking framework. The reason for using plain JUnit tests together with mocks is mostly speed. With mockito it is pretty easy to mock all the involved GWT MVP infrastructure like activities, places, event bus and even a GWT Remote Procedure Call. Here is an example for a presenter test:

@RunWith(MockitoJUnitRunner.class)
public class ContactListActivityTest {

	@Mock
	private IClientFactory clientFactoryMock;

	@Mock
	private PlaceController placeControllerMock;

	@Mock
	private IContactListView contactListViewMock;

	@Mock
	private AcceptsOneWidget acceptsOneWidgetMock;

	@Mock
	private IContactServiceAsync contactServiceAsyncMock;

	@Mock
	private EventBus eventBusMock;

	private List contacts;
	private Contact contact1;
	private Contact contact2;

	@SuppressWarnings("unchecked")
	@Before
	public void setUp() throws Exception {
		when(clientFactoryMock.getPlaceController()).thenReturn(placeControllerMock);
		when(clientFactoryMock.getContactListView()).thenReturn(contactListViewMock);
		when(clientFactoryMock.getContactService()).thenReturn(contactServiceAsyncMock);

		// Mock a GWT RPC
		Answer answer = new Answer() {
			@Override
			public Void answer(InvocationOnMock invocation) {
				Object[] args = invocation.getArguments();
				AsyncCallback> asyncCallback = (AsyncCallback>) args[0];
				contact1 = new Contact();
				contact1.setFirstName("Kai");
				contact1.setLastName("Toedter");
				contact1.setEmail("kai@toedter.com");
				contact2 = new Contact();
				contact2.setFirstName("Kai2");
				contact2.setLastName("Toedter2");
				contact2.setEmail("kai2@toedter.com");
				final List contacts2 = new ArrayList();
				contacts2.add(contact1);
				contacts2.add(contact2);
				asyncCallback.onSuccess(contacts2);
				return null;
			}
		};

		doAnswer(answer).when(contactServiceAsyncMock).
                getAllContacts(any(AsyncCallback.class));

		// set the real contacts object, when clientFactory.setContacts is
		// called
		Answer setContactsAnswer = new Answer() {
			@Override
			public Void answer(InvocationOnMock invocation) throws Throwable {
				contacts = (List) invocation.getArguments()[0];
				// System.out.println("answer() to setContacts(): " + contacts);
				return null;
			}
		};

		doAnswer(setContactsAnswer).when(clientFactoryMock).setContacts(any(List.class));

		// Return the real contacts object, when clientFactory.getContacts is
		// called
		Answer> getContactsAnswer = new Answer>() {
			@Override
			public List answer(InvocationOnMock invocation) throws Throwable {
				return contacts;
			}
		};

		doAnswer(getContactsAnswer).when(clientFactoryMock).getContacts();
	}

	@Test
	public void testGotoPlace() {
		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(null), clientFactoryMock);

		ContactPlace contactPlace = new ContactPlace("kai@toedter.com");
		contactListActivity.goTo(contactPlace);

		verify(placeControllerMock).goTo(contactPlace);
	}

	@Test
	public void testStartWithEmptyToken() {
		clientFactoryMock.setContacts(null); // force RCP
		ContactListActivity contactListActivity =
                   new ContactListActivity(new ContactPlace(""), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

		verify(contactListViewMock).setPresenter(contactListActivity);
		verify(contactListViewMock).initialize(contacts);
	}

	@Test
	public void testStartWithToken() {
		String token = "kai@toedter.com";
		clientFactoryMock.setContacts(null); // force RCP

		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(token), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);

		verify(contactListViewMock).setPresenter(contactListActivity);
		verify(contactListViewMock).initialize(contacts);
		verify(contactListViewMock).selectInitialContact(contact1);
		verify(eventBusMock).fireEvent(any(ContactViewEvent.class));
	}

	@Test
	public void testMayStop() {
		ContactListActivity contactListActivity =
                new ContactListActivity(new ContactPlace(null), clientFactoryMock);
		contactListActivity.start(acceptsOneWidgetMock, eventBusMock);
		contactListActivity.mayStop();

		verify(contactListViewMock).setPresenter(null);
	}

	@Test
	public void clientFactoryTest() {
		List testList = new ArrayList();
		clientFactoryMock.setContacts(testList);
		Assert.assertNotNull(clientFactoryMock.getContacts());
	}
}

If you are interested in above stuff and happen to be in Munich on January 23th 2012, join my Night School, 6:30pm at the OOP 2012.

Have Fun!

Kai

You find me on Twitter and Google+.
Next Eclipse RCP 3.x/4.x trainings in Munich

flattr this!

January 15, 2012

Stefan Winkler
Stefan Winkler

Separating the Wheat from the Chaff — Or: How to Sort Bugzilla Mails

One challenge in my daily work with my email is dealing with automated mails from Hudson or Bugzilla. As I am involved with several customer projects, I cannot keep track of all the Eclipse committer-related mail during the day.

As I am using GMail, I have become used to the mail filtering mechanism GMail offers to make email sent from Bugzilla or Hudson bypass the inbox and land in a separate IMAP folder (GMail uses a label metaphor, but when accessing mails via IMAP, GMail labels are mapped to IMAP folders).

Until recently, however, there was one problem, which I had not solved for months. As perhaps a lot of people do, I am not only receiving Bugzilla notifications related to bugs for which I am reporter, assignee, or on the CC list, but I also watch other Bugzilla accounts; most notably I, follow the emf.cdo-inbox@eclipse.org Bugzilla notifications to keep myself up to date (at least theoretically ...) with all the current bugs of CDO. The problem was that I wanted to separate the more important notifications (those for which I am reporter, assignee or explicitly part of the CC list) from the less important ones (namely those to emf.cdo-inbox). Most of the time (and here comes practice ...), I have too little time to dig through all the Bugzilla notifications and identify the important ones which I should really care about (or at least read) right now.

 

Of course, this is not a fault of Bugzilla, as Bugzilla sets really useful headers for its emails. In particular, the mails which I denoted as "more important" above can be identified by checking the content of the X-Bugzilla-Reason header. If this header contains CC, Reporter, or AssignedTo, I regard the notification as important. The actual problem is that GMail does not support filtering emails by arbitrary headers (or at least they have hidden that feature so well that I did not find it ...)

To solve the problem for me, I have not installed a small Unix utility called IMAPFilter on my virtual server which I am also using to host this blog. IMAPFilter can be configured via a config file written in the Lua programming language. This way, one can write arbitrary (and sophisticated, if needed) rules and commands to process email stored on one or more IMAP servers. In my case, a quite simple config file does the trick (Note: I still use GMail filtering rules to sort Bugzilla emails into the CDO/Bugzilla folder, because this was configured already, and it makes the IMAPFilter configuration a bit easier):

config.lua

myaccount = IMAP {
   server = 'imap.googlemail.com',
   username = 'myself@googlemail.com',
   password = 'S3cr3t!!!',
   ssl = 'ssl3'
}

results = myaccount['CDO/Bugzilla']:contain_field('X-Bugzilla-Reason','Reporter') 
  + myaccount['CDO/Bugzilla']:contain_field('X-Bugzilla-Reason','CC') 
  + myaccount['CDO/Bugzilla']:contain_field('X-Bugzilla-Reason','AssignedTo') 

results:move_messages(myaccount['CDO/Bugzilla-Important'])

(Note: the plus signs have to be read as logical OR)

That's almost it. The config.lua file goes into ~/.imapfilter and to execute the utility on a regular basis, I have created a crontab entry which calls imapfilter all 15 minutes:

0,15,30,45 * * * *     /usr/bin/imapfilter

Naturally, the above is only a simple example. Experiment for yourself to unleash the power of complex mail sorting.

Stephan Herrmann
Stephan Herrmann

A little statistics of the day

My latest query in Eclipse’s bugzilla answered 189 bugs.

Out of these a certain TLA was mentioned just in the bug summaries 54 times.
Additionally, the long form of the same word occurred 5 times.

Those who have followed my previous posts, know which three letters I’m referring to. Looks like they’re even more relevant in some Eclipse components than I ever fancied (no - not telling, in which component I searched :) ).

January 14, 2012

Lars Vogel
Lars Vogel

WindowBuilder with Eclipse 4.2 / 3.8 (Linux)

Currently, if you trying to use WindowBuilder under Linux with Eclipse 3.8 / Eclipse 4.2, it renders incorrectly.

Add the following line to the end of your eclipse.ini file to fix this:

-Dorg.eclipse.swt.internal.gtk.useCairo=false

This is a small bug in SWT and properly will be fixed soon. See Bug Report for details.

flattr this!

January 13, 2012

Wayne Beaton
Wayne Beaton

Open Source Rules of Engagement

The Eclipse Development Process (EDP) defines–in its section on principles–three open source rules of engagement: Openness, Transparency, and Meritocracy:

Open – Eclipse is open to all; Eclipse provides the same opportunity to all. Everyone participates with the same rules; there are no rules to exclude any potential contributors which include, of course, direct competitors in the marketplace.
Transparent – Project discussions, minutes, deliberations, project plans, plans for new features, and other artifacts are open, public, and easily accessible.
Meritocracy – Eclipse is a meritocracy. The more you contribute the more responsibility you will earn. Leadership roles in Eclipse are also merit-based and earned by peer acclaim.

In more concise terms, transparency is about inviting participation; openness is about actually accepting it; and meritocracy is a means of limiting participation to those individuals who have demonstrated the desire and means to actually participate.

Transparency is one of those things that I believe most people understand in principle. Do everything in public: bug reports are public, along with all discussion; mailing lists are public; team meetings are public and minutes are captured (and disseminated). By operating transparently, the community around the project can gain insight into the direction that the project is moving and adjust their plans accordingly.

In practice, however, transparency is difficult to motivate in the absence of openness. What is the value to the community of discussing every little detail of an implementation in public? Does anybody really care? The fact of the matter is that a lot of people really don’t care. Most users of Eclipse are blissfully unaware that we even have bug tracking software and mailing lists. But some people do care, and transparency is a great way to hook those people who do are and get them to participate.

A lot of open source projects understand transparency. A lot, however, don’t understand openness. They’re not the same thing. To be “open” means that a project is “open” to participation. More than that, an “open” invites and actively courts participation. Participation in an open source project takes many forms. It starts by creating bug reports and providing patches, tests, and other bits of code. Overtime, contribution increases, and–eventually–some contributors become full-blown members of the project. Courting the community for contributors should be one of the first-class goals of every open source project.

But openness isn’t just about getting more help to implement your evil plans for world domination. It’s also about allowing participants to change your evil plans for world domination. Openness is about being open to new ideas, even–as the EDP states–if those new ideas come from your direct competitors in the marketplace. A truly open project actively courts diversity. Having different interests working together is generally good for the overall health of an open source project and the community that forms around it.


January 12, 2012

Saurav
Saurav

Eclipse Tips -Part 4

After quite a long time i chanced upon some UI programming. So the thought of putting the next edition of Eclipse Tips came to my mind.

File Browsing Dialog 


It may happen that you would like to browse for a file in the file system and then select it for further processing.Remember how you browse for projects when you import projects from your local file system.

The File browsing dialog can be brought by using FileDialog. You can also use the FileDialog to filter on the file names, extensions etc through the APIs such as public void setFilterNames (String [] names) and public void setFilterNames (String [] names) respectively.

This is how you can use FileDialog in your code


 FileDialog dialog = new FileDialog(parentComposite.getShell());

EMF Unparseable content

I also ventured into some intricacies of EMF Models.Part of my work was to evaluate the possiblity of sending non parseable content through the EMF Models. So i finalized two options Base64 Binary and CDATA.CDATA being the standard way caught my attention first. Here is the link which describes the difference CDATA and Base64 Binary. http://forums.devx.com/showthread.php?t=4667

CDATA


 In EMF you can pass the CDATA if you annotize your model with the mixed content.Please follow the steps to model a mixed content.

(a) Define the EClass for which you want to have the mixed content.Lets say I want to send my java script code through my Request EClass.
So i would define an EClass saying Request.Annotate the Request class by giving the source as Source http:///org/eclipse/emf/ecore/util/ExtendedMetaData.

(b) Create a new Details Entry value for that annotation with name as 'request' and kind as 'mixed'.So it makes the Request class to contain an attribute of type mixed content.

(c) Then define the actual attribute which will contain the mixed content for e.g. JSCode of type EFeatureMapEntry Then annotate JSCode with ExtendedMetadata and then put the Details Entry value with name as mixed and kind of elementWildCard.

How to add the CDATA from your code

//get the instance of the Request class


FeatureMapUtil.addCDATA(request.getJSCode(),"js code");


The FeatureMapUtil adds the CDATA to your mixed content attribute.

Another example i do is for the famous ExtLibrary model. I add an attribute called content in the Library class which contains the mixed content.Below is the xml of the ecore for that part.For this blog purpose i have removed all the other attributes and references of the Library class.



Check how the Library is class is told to contain a mixed attribute and then attribute called content is added which is the actual mixed content.

Base64 Binary


I also tried to explore the Base64Binary way of passing the content.

It is very simple as how to pass the Base64 binary data.Just create the attribute of type Base64Binary.EMF comes with a datatype built in for that.

I end this post here.

Happy working on eclipse.

Neil Bartlett
Neil Bartlett

Free OSGi BOF at DevCon 2012

The programme for the Birds-of-a-Feather (BOF) session at OSGi DevCon 2012 – co-hosted with EclipseCon 2012 – has been announced. I will be speaking about the Java 8 module system, Jigsaw and how they relate to OSGi: what are the differences; the pros and cons of each in different environments; and the potential for them to work together.

There will also be sessions on: OSGi Subsystems; simplifying development with the upcoming OSGi Bundle Repository (OBR) standard; and finally a surprise session from a mystery speaker.

The BOF is free to attend, you don’t need to be registered for OSGi DevCon/EclipseCon. So if you’re in the Washington DC area and interested in learning more about OSGi or meeting several of the top OSGi experts… you know where to go.

January 11, 2012

Neil Bartlett
Neil Bartlett

OSGi Training in 2012; London, NY, DC and Sydney

I will be running a series of OSGi training courses this year, with the first two being held in London and New York in February. The early bird pricing for London will expire in the next couple of days, so please do hurry to secure your place!

If you’re in North America and can’t make NY in February then there will be another chance to take the training in the Washington DC area (very close to Dulles airport). Then later in the year I will be down in Sydney, Australia.

You might be wondering about the “Masterclass in OSGi” series that I previously ran with Peter Kriens, who recently announced his resignation from the OSGi Alliance. Peter is very busy completing his duties for the Alliance and then will be fully engaged with his next venture, so he has told me that he is not able to participate in the masterclasses for the foreseeable future.

My new course is heavily based on the subjects and discussions that arose from the masterclasses that took place in 2010/11, though it is intended to be more accessible for OSGi beginners. I still believe it’s the absolute best way to quickly achieve a deep understanding and mastery of OSGi and modularity in Java, and I very much look forward to seeing you there.

Peter Kriens
Peter Kriens

Java Generics are a Lemon

After working with Java for almost 15 years and deep knowledge of Java generics on the class format level I learned something very basic the really, really hard way. I knew the collections in Java were not that good in comparison what you find in other environments (immutable anyone?) but now I learned that even adding all that extra cruft on my classes is useless when you have a major

Wayne Beaton
Wayne Beaton

Active Projects

I ran a query against Dash to get some sense for project activity over the past couple of years. The graph below shows a comparison of how many active projects we have at Eclipse, compared against the total number of projects.

For the purposes of this graph, I have defined a project as active in any month if it had at least one commit in that month.

I’ve observed a couple of interesting things. First, total number of projects (top line) seems to increase at a pretty regular rate. There are two significant drops in the total number of projects that align with the retirement of projects in the DSDP Restructuring of 2010 and the great Technology Subproject Culls of 2010 and 2011.

The other thing that I’ve observed is that the number of active projects is relatively stable. I’m not sure exactly what to make of this information. It’s worth noting that the number of active committers (using the same definition of “active” is also stable through the same time period).

The coincidental drop offs in December 2011 are also interesting: one might conclude that we must have killed off some active projects. That’s not the case. None of the nine Technology subprojects that were terminated and archived in that period had a single commit in all of 2011. 186 Eclipse projects made at least one commit in 2011. Of the 186 Eclipse projects that made commits in 2011, 58 did not make commits in December. 20 Eclipse projects that made commits in November 2011 did not have any commits in December. There were 5,598 total commits in November, but only 4,691 in December. I have to conclude that it has something to do with Santa Claus. Or Pirates.


Philip Wenig
Philip Wenig

Waiting for Java7 on Mac OS X 10.6.3 “Snow Leopard”

Somehow, it was a good decision to switch OpenChrom to Eclipse 3.7.1 (Indigo) and Java7 except of Mac 10.6.3 “Snow Leopard”. Why on earth do they not support Java7? I don’t know. But I was aware of, that I needed a quick workaround to make it running.

Hence, here’s my solution how to start RCP applications on Mac OS X using Java7:

First of all, create the folder “JavaVirtualMachines” in the directory “/Library/Java“. Unless it’s not created, you’re not able to install the Java7 Developer Preview.

user$ sudo mkdir /Library/Java/JavaVirtualMachines

You can choose between the JDK or JRE package. I took the JDK.

Install it by dragging it into the specified folder.

Now, we need to create a program specific launcher called “start.sh“, but you’re free to choose nearby any name you like. Therefore we dive into the application.app (in this case openchrom.app).

Create a file called “start.sh“.

The content of the starter “start.sh” depends on the specific settings of your RCP application. I took the settings from the application.ini file (in this case openchrom.ini).

#!/bin/sh

export JAVA_HOME=/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home
LAUNCHER_JAR=../../../plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar

java \
-Xms128M \
-Xmx500M \
-Dosgi.install.area.readOnly \
-Dosgi.configuration.area=@user.home/.openchrom/0.6.0/OpenChrom/configuration \
-Dosgi.instance.area.default=@user.home/OpenChrom/workspace \
-Dsun.awt.xembedserver=true \
-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts \
-jar $LAUNCHER_JAR

Start the terminal and navigate to the “start.sh” script. It is necessary to set the executable bit once using “chmod a+x“. The RCP application can now be started by starting the script using “./start.sh“.

user$ cd Desktop/0.6.0-PREV/OpenChrom/openchrom.app/Contents/MacOS/
user$ chmod a+x start.sh
user$ ./start.sh

This tutorial presented a workaround for OpenChrom. But it is applicable in the same way for Eclipse and other RCP applications.


Sven Efftinge
Sven Efftinge

Upcoming Presentations on Xtext / Xtend

There will be a couple of opportunities to learn about the Xtext / Xtend technology stack in the next couple of months. Here are the dates:

Hope to see you there!

Sven Efftinge
Sven Efftinge

I like free beer!

Did you know about http://99-bottles-of-beer.net?
They list programs generating lyrics for a song about beer in 1440 different programming languages (it will be 1441 very soon ;-)). These are the lyrics to generate.

So here is a version written in Xtend:



It uses a couple of interesting features:
Seriously, I think this is one of the most concise and readable versions. Compare yourself.

Ed Merks
Ed Merks

Modeling Daze to Come

My transition to Germany is nearing completion. I now have a three year visa to stay in Germany and I'm registered as living in Berlin. Amazingly the visa was acquired with roughly eight hours of time investment, including the four hour wait for the appointment, along with zero euros of financial investment. The best things in life are free.


The German process stands in sharp contrast to the Canadian process we followed for Frank. That cost many thousands of dollars and took the better part of a year. All I need now is a German tax number and a German bank account and I'll be ready for business in 2012. Speaking of business, there's a lot going on! Jonas recently blogged about the Eclipse Modeling Symposium scheduled for EclipseCon. If you'd like an opportunity to showcase Really Cool Things,™ please send in your proposal so that Jonas and I can find an appropriate slot for your facet.


The OMG is holding an Eclipse Symposium as well. It will be held the day before EclipseCon starts, i.e., Sunday, March 25th, 2012. It will focus on Eclipse technologies that implement and support OMG specifications. Ed Willink is helping organize it. If you're interested, I suggest you contact him at ed at willink dot me dot uk . You can also register just to attend. I'm looking forward to seeing the juxtaposition of the old and the new.


As you may have noticed, you simply can't have too many Modeling Days, so of course there will be another modeling day at JAX this year. Sven, Eike, and I are organizing it. If you'd like to get involved, please send your proposal to ed dot merks at gmail dot com. I expect I'll be able to understand more of the German content this year than I did last year. Maybe I'll even have plodded along far enough to speak some broken German by then.


To further round off an already well rounded event schedule, there's an Eclipse Day in Florence on May 4th. Can you think of a lovelier place to hold a Eclipse event? We're really looking forward to having a peek at part of the community we've seen less frequently.


At this point you might be wondering about deadlines for submissions. All I can say is don't ask about deadlines! Do it now. There's no time like the present. Time waits for no one, and most especially not for you. If you have time, and you expect to be in Berlin, Eike and I will be at the Eclipse User Group Stammtisch on January 31st.

Kai Toedter
Kai Toedter

My Upcoming Events & Sessions

In the next months I am going to give sessions/trainings at several conferences and other events, mostly Eclipse related. I’d be happy to meet you there.

January 20th, 7:00 pm (free event):
Java User Group Ostfalen, Braunschweig, Germany:
Was ist neu bei der Eclipse Rich Client Platform 4.x?“,

January 23th, 6:30 pm:
OOP 2012, Munich, Germany:
Google Web Toolkit: Ausgewählte coole Features“,

January 26th, 11:00 am (free event):
Oracle Developer Day, Munich, Germany:
JavaFX 2.0 Integration with the Eclipse 4.x Application Platform“,

March 26th, 1:00 pm:
EclipseCon 2012, Reston, USA:
Creating Rich Clients with Eclipse RCP 4.x“,
3 hour tutorial

March 28th, 1:30 pm:
EclipseCon 2012, Reston, USA:
Dynamic RIAs with OSGi and Vaadin“,

April 16th – 19th:
Jax 2012, Mainz, Germany:
“Dynamische RIAs mit Equinox und Vaadin”,

April 20th, 9:00 am:
Jax 2012, Mainz, Germany:
Rich-Client-Entwicklung mit Eclipse RCP 4.x“,

April 23th, 9:00 am:
3 days training in Munich, Germany:
Eclipse Rich Client Platform 3.x: Fundamentals“,

April 26th, 9:00 am:
1 day training in Munich, Germany:
Eclipse Rich Client Platform 3.x: Advanced“,

April 27th, 9:00 am:
1 day training in Munich, Germany:
Rich Client Development mit der Eclipse 4 Application Platform“,

Have Fun!

Kai

You find me on Twitter and Google+.

flattr this!

January 10, 2012

Vojimir Golem
Vojimir Golem

How to install and run Dart Editor

In this short screencast (2:30 min) you will see how to install and use new Google Dart editor (currently in alpha).





Share and enjoy!

Holger Voormann
Holger Voormann

Moving Forward – Vex 1.0.0 M8

Vex has moved from being a component in the WTP Incubator project to being a project on its own in Mylyn Docs. Like all other Eclipse projects Vex has its own home page: eclipse.org/vex. Our project lead is Florian Thienel, currently the 99% of Vex (only you can change this).

1.0.0 M8

Last week milestone 8 was released. If you already use Vex then you have to migrate your vex-plugin.xml files. Otherwise you should give Vex a try to edit XML files word processor like.

The next big thing is XML Schema support in addition to the good old DTDs. Already 1.0.0 M8 contains basic support for it. At the moment you have to register the XML Schema manually by editing the vex-plugin.xml file – the UI to do this is under development. So stay tuned. Vex is moving forward slowly but surely.


Flattr this


Alex Ruiz
Alex Ruiz

Associating Xtext editors to file names, instead of file extensions

I’m currently working on a Xtext-based editor for Google’s BUILD language, as described in our Google Engineering Blog. BUILD files do not contain an extension, they are simply named “BUILD.” This naming convention made working with Xtext quite challenging. I needed to change Xtext’s default behavior: instead of associating Xtext editors to file extensions, I needed to associate them to file names. In this blog post I’m describing how I was able to accomplish this.

In this post I’ll be using a brand-new Xtext project. To keep things simple, I’ll use the default file extension (mydsl) and grammar. You can get the source code of this post from Xtext Samples, a new open source project where I plan to store the code I use in Xtext-related posts. All code is released under the Eclipse Public License (EPL) 1.0.

The following steps assume we are going to associate our Xtext editor with the file name “MyDsl.”

  1. Modify the plug-in’s XtextEditor to make it understand file names, instead of file extensions.
  2. Create a ContentHandler that describes the content of files with name “MyDsl.” As part of this step we need to create a new content type for “MyDsl” files.
  3. Create an IResourceServiceProvider that provides services (e.g. validation, content description, encoding) to files with name “MyDsl.”
  4. Register the classes created in the previous steps, to make them visible to EMF and Xtext.

1. Modify the plug-in’s XtextEditor to make it understand file names

This is the easiest of all steps:

  1. Open the file plugin.xml in the “ui” project.
  2. Select the “plugin.xml” tab at the bottom of the editor, to edit the XML code directly.
  3. In the editor element, replace extensions="mydsl" with filenames="MyDsl"

2. Create a ContentHandler that describes the content of files with name “MyDsl”

Here is a simplified version of our ContentHandler. You can find the complete file here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MyDslContentHandler extends ContentHandlerImpl {
  public static final String MY_DSL_FILE_CONTENT_TYPE = "com.google.eclipse.MyDsl";
 
  @Override public boolean canHandle(URI uri) {
    return isMyDslFile(uri);
  }
 
  @Override public Map<String, Object> contentDescription(URI uri, InputStream inputStream,
      Map<?, ?> options, Map context) throws IOException {
    Map<String, Object> description = super.contentDescription(uri, inputStream, options, context);
    if (canHandle(uri)) {
      description.put(VALIDITY_PROPERTY, VALID);
      description.put(CONTENT_TYPE_PROPERTY, MY_DSL_FILE_CONTENT_TYPE);
    }
    return description;
  }
}

Line 2: We define a new content type for “MyDsl” files. We keep the constant public since we will be using it later.
Line 4: We specify that file names with name “MyDsl” can be handled by the ContentHandler. We call the utility method isMyDslFile(URI) from the class URIs.
Line 8: We declare the content of “MyDsl” files as valid and associate its type to the one defined in line 2.

3. Create an IResourceServiceProvider that provides services to files with name “MyDsl”

Here is a simplified version of our IResourceServiceProvider. You can find the complete file here.

public class MyDslResourceServiceProvider extends DefaultResourceServiceProvider {
  @Override public boolean canHandle(URI uri) {
    return isMyDslFile(uri);
  }
}

We call the utility method isMyDslFile(URI) from the class URIs to specify that this IResourceServiceProvider can handle files with names “MyDsl.”

4. Register the classes created in the previous steps, to make them visible to EMF and Xtext

Now it’s time to wire up everything together. First, we bind IResourceServiceProvider to our MyDslResourceServiceProvider in the plug-in runtime module:

  public Class<? extends IResourceServiceProvider> bindIResourceServiceProvider() {
    return MyDslResourceServiceProvider.class;
  }

Now we tell Xtext and EMF, in MyDslUiModule‘s constructor, to understand files named “MyDsl.”

public class MyDslUiModule extends AbstractMyDslUiModule {
 
  public MyDslUiModule(AbstractUIPlugin plugin) {
    super(plugin);
    configureXtextToWorkWithFileNames(new InjectorProvider());
  }
}

We pass an InjectorProvider that obtains the plugin’s Injector only at the moment when it is needed. At this point we cannot pass the Injector directly, since it has not been fully constructed when configureXtextToWorkWithFileNames is called.

The method configureXtextToWorkWithFileNames(InjectorProvider) is defined in XtextSetup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
final class XtextSetup {
 
  static void configureXtextToWorkWithFileNames(InjectorProvider injectorProvider) {
    register(new MyDslContentHandler());
    register(new ResourceFactoryDescriptor(injectorProvider));
    register(new ResourceServiceProvider(injectorProvider));
  }
 
  private static void register(ContentHandler h) {
    ContentHandler.Registry registry = ContentHandler.Registry.INSTANCE;
    registry.put(HIGH_PRIORITY, h);
  }
 
  private static void register(Resource.Factory.Descriptor d) {
    Resource.Factory.Registry registry = Resource.Factory.Registry.INSTANCE;
    registry.getContentTypeToFactoryMap().put(MY_DSL_FILE_CONTENT_TYPE, d);
  }
 
  private static void register(Provider<IResourceServiceProvider> p) {
    IResourceServiceProvider.Registry registry = IResourceServiceProvider.Registry.INSTANCE;
    registry.getContentTypeToFactoryMap().put(MY_DSL_FILE_CONTENT_TYPE, p);
  }
}

Line 4: We register the ContentHandler we created in step 2.
Line 5: We associate the IResourceFactory in the plug-in’s Guice module with the content type defined in step 2.
Line 6: We associate the IResourceServiceProvider we created in step 3 (and later on registered in the plug-in’s Guice module) with the content type defined in step 2.

Testing the editor

To run the editor, right-click any of the projects and select “Run As” > “Eclipse Application” from the context menu.

Here is a screenshot of the editor opening a file named “MyDsl”

Summary

In this post I have shown how to make Xtext understand file names in four easy steps. You can find the code for this post in the project Xtext Samples. You can checkout the code, browse it or download it.

Even though I spent a good amount of time reading Xtext and EMF code to figure this out, I cannot claim my solution is the best one. Please let me know if you know a better way to do what I described in this post :)

Feedback is always welcome.

Lars Vogel
Lars Vogel

Making the Android SDK source code available in Eclipse

As of Android 4.0 the integration of the Android SDK source code is much easier.

You can just download the source code via the Android SDK Manager. The sources are downloaded to the source directory located in “path_to_android_sdk/sources/android-xx”. xx is the api level number (15 for 4.0.3). You can then add the source code as a source attachment to your android.jar.

I included this info in my Android Tutorial.

Thanks to Ed Burnette for pointing that out on Google+.

Kudos also the the ADT team which made this great improvement in development experience.

flattr this!

Roy Ganor
Roy Ganor

A (Big) Dot Release

Although dot releases don't get as much attention as major releases , this one should definitely get highlighted:

      "Zend is pleased to announce the release of Zend Studio 9.0.1!"

This new release focuses on improving source code editing experience, improving editor performance, smart indentation when pasting code. It also extends the code formatter so PHP comments are well structured. Working with PHPUnit made easier with the addition of smart configuration (and bootstrap)  detection. Community plugins updates provide advanced features with Git, ZenCoding and Symfony2.

The changes include:
  • Improved editor performance for multi-line statements and auto indentation scenarios
  • Adjust indentation when pasting code
  • New code formatter rules for PHP Comments
  • Disable/Enable Code formatter with special @formatter:off/on tags
  • Git history graph
  • PHPUnit auto-detection of configuration (and bootstrap) file
  • Improved PHP Class creation for namespace code generation
  • Easy installation of community plugins ZenCoding and Symfony2 and Twig 
  • Various bug fixes

Miles Parker
Miles Parker

Joining the Tasktop Team

Last week I said that I had some really exciting news to share, and this is it: As of today, I am part of the Tasktop team. I've long been an admirer of Tasktop, for a number of reasons...

First, as all Eclipse users know already, they've built some really cool Eclipse technology including the Mylyn task-focussed interface. But many companies have built cool open source tools...

More impressive is to take those cool ideas, discipline them and build a growing, dynamic company on top of them. But plenty of companies have also done that...

But what's really impressed me about Tasktop -- what's made me want to join rather than observe the effort -- is that Tasktop has gone far beyond the "packaged solution with bundled service and support" that typifies most open source derived business efforts. Many companies take a "fill-in-the-blank" approach to open source business models, creating a captive open source market around their offering. Tasktop has created and nurtured a healthy open source eco-system around core open source offerings, but it then re-imagines and re-purposes the technology, leveraging that technology and expertise to uniquely address real customer pain. That takes real vision, and to me it's a clear signal that the Tasktop leadership is able to imagine and execute at an entirely different energy level.

So I first approached Mik and David in the middle of last year to discuss what they were doing and how I might add real value to the effort. That lead into consulting work with Tasktop last year developing the initial implementation of what has become the Model Focusing Tools project. That was a great opportunity to get to know some of the team and the Tasktop way. Everything I saw then fit nicely with what I'd already intuited. We have a really great combination of engineering excellence, creativity, and light-weight organization.

It's nice to say "we" again after over seven years of working by myself or as part of a small team. Yes, I had a lot of close associations with very smart and capable folks through collaborative science efforts and open source projects, but it just isn't the same thing if you're not working toward a shared set of goals. And I hadn't realized just how much I'd missed having colleagues to work with on hard problems together until I got involved in that last project.

This morning as I've checked in my email, I've been getting emails from everyone at Tasktop welcoming me to the team. I must admit to a bit of cynicism about the whole "team" thing -- like so much else, it often seems an empty set of words that don't match up at all to reality -- but in this case it feels very genuine. So heartfelt thanks to everyone -- I'm working remotely so I won't get to meet you in person right away, but I look forward to it. And don't worry, you won't have to "buy me lunch". ;)

(And yes, I'm afraid to say that you'll still be seeing irreverent and irrelevant blog entries on Eclipse Planet, but I am going to try to keep a closer eye on the four-letter word count.)

Obviously I'm going to be focussed on and very occupied with my new role at Tasktop, and you may be wondering how this will affect the other efforts I'm involved in... With the new Beta, Butterflyzer has grown wings -- or for the crossword lovers out there, it's pre-Imago. That's as much as I can say right now, except I'll continue to keep a close eye on its maturation process. I'll also still be leading the Agent Modeling Platform, doing what I can in my off-time to support builds and provide project leadership. The project provides a wide-array of functionality now, and pretty decent quality. Now it is time for people who are interested in moving the ABM effort forward to step up to the plate with their own time and energy. I think the future of tools for modeling real world systems at Eclipse is very bright.

As I said last week it's an exciting time to be building software tools! I know it sounds funny, but I like to think of software development as a helping profession. That's because I think that software products really can help people live more fulfilling, interesting and even happy lives. And I'm delighted to be at Tasktop helping to create those tools.


January 09, 2012

Martin Lippert
Martin Lippert

open and transparent demo camp sponsoring

Its been a while since Peter Friese and I started to organize the Eclipse Demo Camp in Hamburg. And since the early days, we couldn't have done it without companies sponsoring the event so that we could sit in a nice location, have free drinks and quite often even free food for everybody joining us to watch great demos and great speakers.


Since sponsoring was always an important part of organizing that event, we decided to try something new in this area. For the next demo camp (the Juno release camps in the summer of 2012), we try a totally open and transparent sponsoring. Everybody is invited to join us sponsoring this event. All you (as a sponsor) need to do is: register yourself as a sponsor on the demo camp wiki page with your name and the amount of money you would like to spend. And we explicitly invite everybody: from big companies spending several hundreds of Euros to individuals spending only a few bucks. Every single Euro is welcome and highly appreciated.

The sponsoring will have absolutely zero effect on the selection of speakers or demos and we continue to have no sponsored talks or company presentations at the beginning (the only exception to this is if the management of the company that is giving us the room for free is asking for a small intro at the beginning, but we try to avoid that as well). And attendance will be free, as usual... :-)

Ah, one more thing: We will donate 20% of the food/drinks that we order for the event to a local organization that helps homeless people. We think its not fair when we sit inside having more food than we can eat and having other people sitting on the street being hungry. Therefore 20% of all the drinks/food that we order will be delivered directly to that organization on the evening of the demo camp.

Karl Beecher
Karl Beecher

Eclipse trainings available

I delivered my first Eclipse training just before Christmas last year. I’m happy to say that the clients, just under a dozen programmers working for a large German corporation, have reported being “very satisfied” with my two-day seminar. I’m also happy to say I enjoyed it even more than I thought I would, probably due to the lack of nervousness I thought I might experience. In fact, I was so at ease and enjoying myself, I’m now hugely looking forward to delivering it again for other clients.

For anyone who wishes to know more about the Eclipse training I provide (perhaps you’re interested in it yourself?) here’s the basic overview:

  • Downloading and installing
  • Introducing the working environment (workbench, views, perspectives)
  • Programming using the editor, basic functions
  • Backup and versioning, local history
  • Using plug-ins and updates sites
  • Project administration
  • Features for object-oriented programming
  • Features for Java development
  • Debugging and Running programs
  • GUI development using visual editors
  • Automated testing using JUnit
  • Version control using Subversion and Subclipse
  • Developing UML diagrams
  • Editing XML files
  • Plug-in development
  • Practical tips and tricks

These subjects are by no means carved in stone, but they certainly embody what is necessary for beginners to learn (with the possible exceptions of UML, XML and plug-in development) and represent what can be covered in a minimum of two days. Beyond that, my curriculum is flexible and open to discussion.

If you’re interested in knowing more or booking a training, then please feel free to get in touch via mail@karlbeecher.com.

Glyn Normington
Glyn Normington

New Releases: Virgo 3.0 and Gemini Web 2.0

Virgo 3.0 and Gemini Web 2.0, collectively known as the Maya release, are available for download and download, respectively.

The team of committers has expanded considerably and, although the team is now distributed geographically, we have a great working relationship. I'm delighted that these projects are now community collaborations rather than the work of a single vendor.

The theme of Virgo 3.0 is better integration with EclipseRT technologies. To that end, we have created a Jetty variant of the Virgo web server and have switched from Felix to Equinox implementations of some OSGi services. Integration with p2 is proving a tough nut to crack and is deferred to the Bondi (3.5) release, although we expect to issue a milestone soon to get some feedback from the user community.

Gemini Web and the Tomcat variant of the Virgo web server have been upgraded to Tomcat 7 and Servlet 3.0.

Gemini Web 2.0 passes the OSGi Web Applications compliance tests and will replace the SpringSource OSGi Web Container as the OSGi Web Applications reference implementation.

The snaps framework for modular web applications is also released as part of Maya. This started life as the SpringSource slices prototype.

Virgo kernel 3.0 has a new shell based on Apache Felix Gogo for both the kernel and user region and accessible via telnet or ssh.

The 3.0 kernel also uses a new implementation of regions, the region digraph, based on OSGi standard framework hooks. The digraph should position Virgo well for implementing the OSGi Subsystems specification in a future release. (The specification is still under development, but we expect a public draft from the OSGi Alliance before long.) The digraph has moved from Virgo to Equinox to enable it to be used by other projects, especially those that are aiming to implement the Subsystems spec.

Highlights:

See the release notes for details.

Eclipse Gyrex
Eclipse Gyrex

How we do release engineering?

One of the challenging parts at Eclipse is doing the release engineering work. Large projects may have dedicated resources as well as well established processes. We don’t. However, I like the way the Eclipse project is doing their builds. They have (over simplified) a “version.properties” file that contains a list of bundles and a SCM tag to use. They are called map files and they drive the build.

For a long piece of Eclipse history, the map files were tagged manually by hand. Whenever a committer modified a bundle (aka. plug-in or feature). He also had to release those changes by tagging the bundle and updating the map file. When the Eclipse project migrated to Git they automated this process. A script is started before the real build begins. The script scans a branch for new commits since the last tag. If any new commits are found, the repository will be tag with a new tag and the map file will be updated.

I started migrating Gyrex to Git last week. The CVS to Git part was easy. Our build is running again. Thanks to an update to PDE Build it fully supports Git map files. Our process has always been as close to the Eclipse project as possible. We also use the map files which drive our build. We also used to tag our (CVS) projects by hand and we also used to update the map files by hand. Now with the change to Git we’ll also stop doing that.

I took the scripts from the Eclipse project and adapted them. We don’t run the script as part of our Hudson build job. Due to security concerns, the Hudson machines aren’t able to push changes back to Git repos. Thus, I run the tagging scripts on build.eclipse.org by cron. At the end of the run, a Hudson build will be triggered by the script via and Hudson API call.

You can find the scripts here:
gyrex-releng.git/tree/org.eclipse.gyrex.releng/builder/environments/build.eclipse.org/tagging


Filed under: Documentation, Updates Tagged: CVS, Git, Releng

January 07, 2012

Ekkehard Gentz
Ekkehard Gentz

Git and mobile development (Git branching model)

mobile development == development for different API versions

As you know, the last years I was using Mercurial (hg) as DVCS for my projects.
2012 will become the year of Git ;-)
While I like the easy-to-use-and-understand Mercurial, which is a good way to start with DVCS, the last weeks I experimented using Git for some special workflows not so easy possible using Mercurial.

If you’re developing for mobile devices (doesn’t matter if this is Android or BlackBerry etc) sooner or later you run into the situation that you have to support some platform OS versions.
per ex. for BlackBerry:

  • BlackBerry OS 5
  • BlackBerry OS 6
  • BlackBerry OS 7

there are different strategies how to solve this:

  • manage different projects for each OS Version
  • use a pre-processor
  • encapsulate different API’s in libraries and build different products

both doesn’t make me happy: I don’t want to manage different projects parallel and I also don’t want to use a preprocessor because the code becomes more unreadable with all those if OS5 then….. if OS 6 then….. instructions. Also the library-per-API.-differences solution isn’t really flexible.

So I was looking for new ways HowTo solve this and sketched up what I’ll need.

Reading Al Blues Git Tip of the week: GitFlow I found out that most of my ideas were already published here: A successful Git branching model ;-)

I don’t need it exactly this way, but if you should read the article to get the idea how all will work.

so back to the mobile development.

let’s take an actual example:

logging4bb using a special Git Branching model

Overview

I developed a logging framework for BlackBerry OS 6+. As you probably know, under BlackBerry OS Java you couldn’t use any of the modern logging frameworks like Log4J, SLF4J, LogBack, java.util-logging etc.

Logging is always an important part for my development, so I implemented a logging framework (logging4bb) where I can

  • log to SQlite on BlackBerry
  • or through Socket Connection to Lilith as LogMonitor.

If you followed my blogs you know that I’m using Lilith since years to monitor the logging of OSGi – Equinox applications together with SLF4F / LogBack.

I’m sending LogEvents to Lilith using the same format as LogBack does this using a Lilith Appender, so Lilith doesn’t know that there’s not LogBack but a BlackBerry device sending events.

This works from Simulator and also real Devices through WLAN or CellTower. The best thing: now you can watch log statements from server and mobile clients side-by-side :)

read more here about the logging4bb project itself.

Between BlackBerry OS 6 and OS 7 APIs supporting SQLite and also Remote Command Framework are different, so I wanted to support both OS versions.

Next problem because the project should be Open-Sourced:

The Socket Connection uses BIS (BlackBerry Internet Service), which makes it very easy to switch between WLAN and CellTower and still using the same SocketConnection.

As a BlackBerry partner you’re allowed to use BIS as a free BlackBerry Service in your products (per ex. my Apps in the Appworld), but it’s not allowed to publish the special connection String.

To launch and run the application I have to use the String. How to make development possible with these goals:

  • support different OS versions (API)
  • support public (OSS) and private development
  • support OSS project and Appworld Product

all without the standard ways like pre-processor etc.

public and private repositories

of course I want to use source repositories for the public parts (OSS) and also the private parts (secret connection and also appworld product and/or customer products).

that’s the reason why the projects are hosted at Bitbucket: I can have unlimited private repositories for free.

Great that Bitbuckit also supports both: hg and Git projects.

Git Branching Model

Here’s an example how the branching model could look like from different tools:

EGit:

Tower (OSX):

I’m working with Tower because then it’s easy to have one single place where I can manage all my repositories from Eclipse Workspaces on OSX (my main development) and also Eclipse Workspaces from the unfortunately-Windows-only-BlackBerry development.

Hint: I’m using Parallels and mapped a directory on OSX as Drive W:\ to Parallels-Windows7 running on top of OSX. so I can manage all from Tower on OSX :)

Here’s an overview how my branching model works:

let’s take a look into the details:

Who’s the Master ?

There’s no Master branch as usual, because there are dev-* branches working like a Master branch for the different OS Versions.

The Master only has a readme.txt file with a short description of the branching model.

Then development started with the dev-public Branch – in this case development started with OS 6 API. Some times later after finishing the OS 6 version, the development continues using the newest OS 7, so a branch os6/dev-public was created.

Each branch works like a Master for the specific OS Version.

Hint: I’m using the “/” in the names to get a folder-like structure in tooles like Tower.

What about Bugs ?

Bugfixes only for OS 6 API will be done on the os6/dev-public branch – bugs for all versions will be fixed on the newest branch.

If some parts of the new development or generic branches should be back-ported to the older os6 version, then GIT Cherry-Pick is an easy way to do this.

How to use the “secret” private Repository ?

This repository is only needed in workflows where the project ist Open Source and public, but some parts are not allowed to be publicly visible.

In this special case I need dev-secret* branches, where I add the secret parts. Now it becomes difficult: without the secret connection code I cannot run and test the application or launch the simulator. So normaly I’ll work in the *secret* branches, test-run-change code etc.

But these changes must be part  of the public branches. So after some steps I want to commit and I also want to be sure, that all works from the OSS public branch.

Now GIT Stashing comes into play:

  • all changes from secret branch will be staged
  • then stashed
  • now switching to public branch
  • applying stash to public branch and see if all compiles
  • committing to public branch
  • pushing to remote public OSS repository
  • switching back to secret branch
  • merging public branch into secret branch
  • pushing changes to private secret repository

sounds complicated, but it works very well and after some weeks working with this branching model I like the flexibility

How to work with Customer Repositories ?

workflows are easier, I only merge regulary from the public development branches, because normaly special customer-cases won’t be given back to the public area.

but if – from time to time – something should go back: as usual cherry-picking is your friend.

HowTo organize local development Repositories

this is totally up to you how you organize your local repositories. It depends from your team-size, project structures etc. some examples what could be done:

  1. One local repo for all Braches of a specific project: You can have one workspace for all branches and always switch between public – secret – customers – OS Versions. Again Stashing can help to make the workspace clean before switching.
  2. One local repo for each platform OS: Then your local Repository has some branches for different projects from different remote repositories, but all for the same OS Version
  3. One local repo for each Customer: Then all Customer Branches will be inside one workspace.

To cherry-pick and move changes back to other branches one member of your development team should have a local Repository like 1.

Local branches

The Branching Model above was all about public remote branches tracked by your local branches.

Of course al the usual workflows work as with ‘normal’ projects referring to a Master Branch only:

create local branches for bugfixes, new features etc.

Hint: if not already done please read the article above: A successful Git branching model

What Users should Clone / Check-Out ?

Users simply clone the public Repository and then have to decide which public branch they should check out and always pull against to get the newest things.

Everyone who only needs the OS 6 version simply checks out the os6/dev-public branch, who needs the newest one checks out dev-public branch. Who needs all, can switch between the branches or have different workspaces for different OS Versions or ….

GIT really makes it easy for everyone to follow their specific workflows and project structures.

Tooling

Tooling is important if you want to manage complex workflows with GIT.

If you’re a friend of the commandline, then you can do it all from there very fast and all options are open to you.

But I don’t like the commandline and prefer UI Tools.

If you’re working with Eclipse only then EGit is the best way to do it. Newest versions of EGit / JGit now are supporting most what GIT provides. If you like Gerrit for code-reviews then again EGit is a good solution.

I’m now using Tower, which is a great UI Tooling for OSX. (Thx @PeterFriese mentioning Tower some time ago at twitter)

With Tower I can manage all my repositories at a single place – doesn’t matter if they’re from OSX – Eclipse workspaces, Windows (on-Parallels) Eclipse workspaces or from non-Eclipse sources.

All the workflows are easy to manage from Tower. The UI is a really good looking OSX UI. I’ll provide some Videos later.

Thanks

…to Al Blue’s Git Tips of the week – series – this is a must-read for everyone starting with Git to understand the power of Git.

I’ll blog some more about my GIT experiences soon as part of my DVCS blogging series.

—————————————————————————————————————————

(c) 2011 Creative Commons License 3.0 (BY-NC-SA) by  ekkescorner 


Filed under: Blackberry, Eclipse, Egit, LOGBack, mobile

January 06, 2012

Miles Parker
Miles Parker

Butterflyzer Beta

When Butterflyzer was launched a year ago it was introduced with the following words:

"Butterflyzer is in Alpha now. Before we release more polished versions, we need to know if people really want it. So if you like it and want to see a full version, follow us on twitter, and tell your friends. If we get 10 followers we'll release an alpha version. If we get 100 followers we'll release a beta. If we get 250 followers, we'll make a nicely packaged version available commercially at a decent price. Simple as that."

A minor problem.. the response was so great that we achieved the Beta milestone in a few months. And the software just wasn't there in terms of Beta quality. Plus, I felt that there were a number of key improvements to the interface and other functionality that just had to be made. So, it's been six months since we hit the milestone, and I'm happy to announce that..

The Beta is Finally Here!

Download Butterflyzer Now

We've had a Beta Preview available for some time, so many of the features won't be news to all of our users, but I think the level of polish -- if you can talk about a beta release having polish -- is pretty good. There will certainly be issues with it (that's why we have betas!) but it is otherwise feature complete and ready to go to version 1.0. If you're wondering how much work has gone into the release, I'll throw out one measure: the Beta release is Build #995. Here are just some of the many issues big and small that we've addressed along the way..

User Interface


The application just didn't fit in well with the target audience and their expectations about how web related tools should look and feel. One of the most important pieces of feedback I heard was that the interface just felt overwhelming. There is a lot that you can do with Butterflyzer, and I wanted to find a way to make that functionality easily accessible while de-cluttering the user environment as much as possible.

The Butterflyzer Alpha was a typical Rich Client (RCP) application built on the rock-solid and powerful Eclipse platform -- the same one that IBM and other leading software companies base their applications on. The downside of that is that the current Eclipse UI support is a bit stodgy. And unfortunately, while the Eclipse environment provides a lot of functionality, it is very difficult to change the overall look and feel. (E4 makes huge improvements in this area, but E4 didn't address all of our requirements and isn't quite mature enough yet.) So we went back to the drawing board, moved a bunch of stuff around, and re-implemented key existing functionality, including interface and workbench components. It wasn't simple to make these changes, but I think they were more that worthwhile. In fact, I think they were necessary. You can build the most powerful, feature-rich program in the world, but if the UI isn't any good, the only people who use it will be the people who don't have any other choice. So yep, we sweated those single pixels.

Browser Look and Feel

In the quest for simplification, Butterflyzer copies the overall presentation of a typical web browser like Safari, Chrome or Firefox. Catalogs are like browser tabs and all of the interface elements are consolidated within them. That means that we've essentially turned the typical end-user application inside out, with all of the tools and views being hosted inside each editor.

Here's what the old application looked like:


And here's chrome, our simplicity bogey:


Here's the new and improved Butterflyzer:


Why so dark?

By the way, if you've wondered why Butterflyzer employs a "light on dark" visual style, it's not that we're trying to be trendy or anything. There are sound reasons for keeping the Butterflyzer elements dark:

  1. Colors are easier to distinguish, connect and even read against a black background, and color plays a critical role in establishing implicit relationships within and between the various Butterflyzer user elements. Remember those old green and amber monitors? They really were easier on the eye.
  2. A dark background allows images to pop and reduces the sense of visual clutter, which is a critical issue given the complexity of the information visualized.
  3. Most web pages and other artifacts are black on white, of course -- keeping the Butterflyzer elements dark helps establish the web page elements as the visual foreground for the user. There is the "content manager" and then there is the "content" -- everything we can do to make that separation clear is helpful.
  4. Because we insert the semantic tags directly into the web pages, we need a way to distinguish them clearly from the rest of the web content, and we want those tags to look like the tags in the other views. OK, it's not always that attractive, but you can always turn the semantic feature off if you just want to look at the web page content.
  5. A dark background allows us to employ more obvious color highlights for buttons themselves. That's important because most of the buttons are monochrome and a simple as possible; we can then color them as appropriate for user interaction.
Plus it looks cool, right?

New Help System

We've implemented a new Help System that includes dynamic help, so that when you scroll over an interface item, you can get live help. Speaking of help, there is a lot of it! And since we have it now, I'll use it to help tell the story.


Eclipse software developers might be interested to know that the majority of the documentation is actually produced directly from our properties files. (Yes, Butterflyzer is fully designed for Internationalization, but we don't have any translations for other languages yet.) That means that we only have to maintain this information in one place. Custom Java code reads the properties and converts them to Wiki text and the help system dynamically loads the property information for context sensitive help, including links to related documentation. From there, we use Mylyn Wiki Text to generate the Eclipse Help system artifacts, online documentation, and even a PDF manual.

Palette Menus

One major goal was reducing the number of mouse-clicks needed to perform common tasks. I think that number and frequency of mouse-clicks have a large effect on end-user perception of ease of use and efficiency for an application. We needed to reduce the proliferation of toolbar buttons without causing a lot of mouse thrashing. Popup menus work fine for supporting changes in options, but they have a big usability issue. Every time you want to make a change, you have to reopen the menu. You could put options into a tool widget as many Apple applications do -- and we do that for more complex settings involving sliders -- but then users have to get rid of it when they're done. Instead, we created our own menu type that displays as long as the mouse is within the target menu area. This required replacing a lot of the normal Eclipse menu implementation.

If you still think all of those buttons are a bit bewildering, you can find out what they all do here.






Context Popups

If a mouse-click takes time and mental effort, a right-click takes even more. There is just something that feels slow and uncomfortable about the whole interaction. I think that's a major issue with the Eclipse user experience actually, and one of the reasons that people like Web interfaces so much -- you see something, you click on it, it does something. Simple. At the same time, it's even worse to have to mouse up to a toolbar to perform a common task on an item. And the worst thing of all is a hover. There is nothing like waiting for a machine that can do billions of instructions per second to take half a second to decide that you want to do something!

In Butterflyzer, we wanted to support a sense of flow when working with items. And we need commonality between the different kinds of views so that for example the options that you have when working with an item in the graph view are the same as when you mouse over the item in the browser. The solution was a context menu that appears automatically . It's still a bit experimental -- there are some usability and consistency aspects to fine-tune -- but I think it works pretty well. Currently you hold down that "CTRL" key in order to make the menu appear on any item -- having it appear in all cases made interaction a bit busy feeling.

Windows


Yes, Butterflyzer has always done Windows. Just not very well, frankly. Apologies to the legions (well, dozens anyway!) of Windows downloaders out there..we think this latest version will make you much happier.


Visualization


There have been significant strides in this critical area as well, including innovative approaches to taming, filtering, and cleaning up visualizations and related data. For more on all of that, check out this section in our comprehensive documentation.

Internals


The list of enhancements here is too long to get into, but we've put a lot of effort into creating a system that has the highest throughput and integration without compromising data integrity. It's been a challenge, and there have to be some gotchas lurking out there, but I'm really happy with how the system is handling the large volume of data that we can pull in. To see what I mean by "large volume of data", check out this page for details on what you get from a single Butterflyzer search.

Web Site


The web site has come a long way from the alpha days, where it was deliberately minimal and home grown. Please visit!

New Videos


If you want to see how this all fits together, check out the new videos:





Let's Talk!


As always, I'd love to hear from you. What are you using Butterflyzer for? What would you like to do with Butterflyzer?

One thing I'd like to mention specifically for people already involved in developing software tools for the Semantic Web: Butterflyzer is an end-user product, but there are many other opportunities for employing core Butterflyzer technology. Perhap you have proprietary or specialized Web information sources that you'd like to integrate with the Butterflyzer Content Management and Visualization services. Perhaps you'd like to license or re-brand Butterflyzer or make use of key components. Contact us and let's discus how you can use Butterflyzer to enhance your efforts.

But what I really hope is that you're someone who just wants a good tool that you can use for web research, and that Butterflyzer scratches that itch for you. I'm reading the new biography of Steve Jobs so I can't help indulging in a little reality distortion of my own -- in the best sense of that phrase, naturally. You'd never know it with all of the talk, but we're still in very early days of semantic technologies, and we're nowhere near exploring the possibility surface, let alone exploiting it. When it comes to web exploration tools, what exists now for the average user is... well, it's a lot of dumb shit, with a nod to Steve. I believe that you need a rich, powerful application to make the most of the deep store of knowledge that is out there, but it needs to be as simple as it possibly can be -- in short, a tool that opens up the Semantic Web for the Rest of Us. And that's what Butterflyzer is all about.

It's an exciting time to be building software tools! There are a lot of interesting things happening, and plenty of opportunities for all of us to make positive changes in how people around the world work and live. I've got some other really exciting news to share, but that will wait until next week...


Eric Rizzo
Eric Rizzo

I've censored the following, in protest of a bill that gives any corporation and the US government the power to censor the internet--a bill that could pass THIS WEEK. To see the uncensored text, and to stop internet censorship, visit: http://americancensorship.org/posts/33408/uncensor

Dave Carver
Dave Carver

New Year, New Challenges

For the last year and half I have been working with eBay through Intalio, on the Turmeric SOA project.   With the new year, I’ll be transitioning off the Turmeric SOA project to an internal Intalio project.   I’ll still be involved with Turmeric, just not as much as I have been in the past.    Turmeric SOA will still be developed and lead by eBay  and hosted on their eBay Open Source portal, and for those that need to support developing and deploying a SOA with in their Enterprise I still think it can be a good fit and something to at least consider.

The new project I’ll be working on gets me back to some of the things I like to do, plus will finally get me to learn some of the newer languages and play with  other technologies.   It should also free me up a bit to address some of the open source projects I’ve had to neglect over the last year at eclipse.  So hopefully, I’ll be able to get to some of the eclipse XSL Tools bugs reports, and maybe..just maybe, I’ll look at Orion and see what it would take to get an XML/XSLT editor going there.

I’ve got a lot of little projects going on at github as well, and I’ve got some ideas around improving the state of  web service documentation that I feel are necessary to explore.   The early part of this year I have some presentations lined up at STAR and HR-XML around REST and Web 2.0.  So I hope to explore how to get organisations like OAGI and related data standard bodies looking at not just XML but how to play well with JSON in the new Web 2.0 world.

So I wish the Turmeric SOA project well, but I’m really looking forward to getting my hands back into some new stuff this year.  Embrace change, good things tend to happen.


Angelo Zerr
Angelo Zerr

Eclipse Nebula Pagination Control

In business application with large data, display data in a table with navigation page can be really helpful. In our XDocReport project, we need this feature in our Eclipse RCP/RAP XDocReport application for instance to select resumes to open in the Search Resume Dialog :

This last screenshot is the resume search dialog in WEB context (Eclipse RAP). Here a screenshot in fat client context (Eclipse RCP) :

After several search, it seems that there is no project which provides a SWT pagination control, which works with Eclipse RCP and RAP. So we decided to develop this control and give our code to Eclipse Nebula Project with the bug 367064. Today Nebula Team are voting if the project will be accepted or not.

Overview

The Nebula Pagination Plug-Ins gives you the capability to paginate data list in any SWT Widgets. It works with Eclipse RCP and RAP too.

Table pagination

Nebula Pagination gives you the capability for instance to manage pagination in a SWT Table :

This screen comes from org.eclipse.nebula.widgets.pagination.example.table.renderers.GraphicsPageableTableExample. Here the page navigation bar is drawn with SWT Graphics Context (GC), and you can change on runtime if you need the control style (or implement your own style). Here black style :

and green style :

You can use another pagination navigation bar renderer. For instance here links renderer: (see org.eclipse.nebula.widgets.pagination.example.table.StringPageableTableExample) :

Nebula Pagination provides another pagination renderer like Combo Page to choose the page, Scale Page to select a page, etc… Here a screenshot where you can see the whole pagination renderer (see org.eclipse.nebula.widgets.pagination.example.table.renderers.AllRenderersPageableTableExample) :

The whole pagination renderer are synchronized with the pagination controller. For instance if you change the selected page in a pagination renderer, the other pages renderer will be synchronized with this new selected page.

Table pagination&sort

You can manage sort with pagination like this (see org.eclipse.nebula.widgets.pagination.example.table.ModelSortPageableTableExample) :

Work In Process

The load of the paginated list could take time. You can observe the before/end loading of the paginated list to display a “Loading…” message. If you launch org.eclipse.nebula.widgets.pagination.example.table.ModelSortPageableTableWorkInProcessExample and you click on a page index (here the 2 page is selected), a “loading” message display on the bottom of the table :

The load of the paginated list takes 1 second and display at end the time of the load of the data :

Lazy loading

Nebula Pagination is able to manage lazy table to load new items when last item of the table is selected (see org.eclipse.nebula.widgets.pagination.example.table.lazy.LazyPageTableExample):

after selecting the last row, it load new data :

Plug-Ins

Nebula Pagination contribution provides 7 Plug-Ins :

  • org.eclipse.nebula.widgets.pagination : Eclipse Nebula Pagination which provides abstract class to manage pagination and implementation of thoses classes with PageResult pagination structure. Eclipse Nebula Pagination defines an IPageContentProvider to work with any Pagination structure (by default it works with Nebula PageResult, but you can use Spring Data Page structure if you wish (see org.eclipse.nebula.widgets.pagination.springdata).
  • org.eclipse.nebula.widgets.pagination.example : sample with table pagination by using Nebula Pagination.
  • org.eclipse.nebula.widgets.pagination.tests : tests of Eclipse Nebula Pagination.

And if you wish use Spring Data pagination structure :

  • org.eclipse.nebula.widgets.pagination.springdata : defines an IpageContentProvider to works with Spring Data Page, Pageable.
  • org.eclipse.nebula.widgets.pagination.example.springdata : same sample than org.eclipse.nebula.widgets.pagination.example but works with Spring Data structure.
  • org.springframework.data.domain-only : Spring Data with just Pagination structure.
  • org.springframework.data.domain.collections : Spring Data domain Collections support.

Nebula Pagination API (without Spring Data)

To manage pagination with SWT table, Nebula Pagination provides a SWT Composite org.eclipse.nebula.widgets.pagination.PageableTable. The use of PageableTable is very easy but before explaining how to use it, it’s interesting to manage pagination at hand with the Nebula Pagination API (page controller etc) to understand more how to work PageableTable. The Nebula Pagination API could be used to manage pagination with another thing like Tree, NatTable, etc.

Pagination in Table at hand

This explanation is based on the sample org.eclipse.nebula.widgets.pagination.example.table.renderers.OneRendererPaginationTableAtHandExample :

Nebula Pagination works with a pagination controller which hold information about pagination and send events when information changes. The pagination controller is used to store information about pagination :

  • the current page index: index of the selected page.
  • the page size: number items to display per page.
  • the total elements: the total elements of the paginated list.
  • the current sort information: the property name and direction of the sort.

The controller fire events as soon as pagination information changes (ex: a new page is selected, sort change,etc). Those information can be observed by adding org.eclipse.nebula.widgets.pagination..IPageChangedListener to the controller. The pagination controller is designed with the class org.eclipse.nebula.widgets.pagination.PageableController which plays the role of the pagination request.

  1. At first you must create a pagination controller like this:
    int pageSize = 10;
    final PageableController controller = new PageableController(pageSize);
  2. For pagination table, a listener is added to the pagination controller to refresh the table with paginated list. To load paginated list, you must implement org.eclipse.nebula.widgets.pagination.IPageLoader :

    package org.eclipse.nebula.widgets.pagination;
    
    import java.util.List;
    
    import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
    import org.eclipse.nebula.widgets.pagination.collections.PageResult;
    
    /**
     * Classes which implement this interface provide methods which load paginated
     * list by using information about pagination (sort, page index etc) coming from
     * the {@link PageableController}.
     * 
     * <p>
     * If you wish to manage pagination with Java {@link List} in memory you can use
     * {@link PageResultLoaderList}.
     * 
     * </p>
     * <p>
     * For better design {@link IPageLoader} should be implemented by the Service
     * Layer or DAO (Repository) layer. If you wish to manage pagination with JPA,
     * Spring Data JPA can be very helpful.
     * </p>
     * 
     * @see http://www.springsource.org/spring-data
     */
    public interface IPageLoader<T> {
    
      /**
       * Load the paginated list by using the {@link PageableController}
       * information about pagination (sort, page index etc) and returns a page
       * result which contains the paginated list and the total elements (ex:
       * {@link PageResult}, Spring Data Page, etc).
       * 
       * @param controller
       *            information about pagination.
       * @return a pagination structure which contains the paginated list and the
       *         total elements.
       */
      T loadPage(PageableController controller);
    
    }

    The implementation of this interface must return the page result structure. Nebula Pagination provides a basic pagination page result org.eclipse.nebula.widgets.pagination.collections.PageResult which works with Java list :

    package org.eclipse.nebula.widgets.pagination.collections;
    
    import java.util.List;
    
    /**
     * 
     * Page result used to store pagination result information :
     * 
     * <ul>
     * <li>the total elements</li>
     * <li>the paginated list</li>
     * </ul>
     * 
     * @param <T>
     *            the type item of the paginated list.
     */
    public class PageResult<T> {
    
    	private final List<T> content;
    	private final long totalElements;
    
    	/**
    	 * Constructor with the given paginated list and total elements.
    	 * 
    	 * @param content
    	 * @param totalElements
    	 */
    	public PageResult(List<T> content, long totalElements) {
    		this.totalElements = totalElements;
    		this.content = content;
    	}
    
    	/**
    	 * Returns the total amount of elements.
    	 * 
    	 * @return the total amount of elements
    	 */
    	public long getTotalElements() {
    		return totalElements;
    	}
    
    	/**
    	 * Returns the page content as {@link List}.
    	 * 
    	 * @return
    	 */
    	public List<T> getContent() {
    		return content;
    	}
    }

    So you can create a page loader like this:

    final List items = ...;
    final IPageLoader<PageResult> pageLoader = new PageResultLoaderList(items);

    If you use Spring Data JPA, the page result structure can be org.springframework.data.domain.Page and implementation of the IPageLoader can call directly a repository interface (ex: Page findAllPageable(Pageable pageable)). If you wish use Nebula Pagination with Spring Data, please read Nebula Pagination API (with Spring Data).

  3. You can create your TableViewer with classic mean and synchronyse it with controller and pageLoader like this :
    Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    ...
    TableViewer viewer = new TableViewer(table);
    controller.addPageChangedListener(PageLoaderStrategyHelper.createLoadPageAndReplaceItemsListener(controller, viewer, pageLoader, PageResultContentProvider.getInstance(), null));
    

    Here when controller changes (ex: page index changes, sort changes, etc), it call the pageloader which returns paginated list in the PageResult and the viewer is refreshed (viewer.setInput(page.gecontent()) with the sublist coming from the PageResult#getContent(). PageResultContentProvider.getInstance() is the org.eclipse.nebula.widgets.pagination.IPageContentProvider to tell that you wish works with page result org.eclipse.nebula.widgets.pagination.PageResult.

    Now if you do :

    controller.setCurrentPage(0)

    to set the current page index to 0, the controller will send an event to notify that page index has changed. In this case, page loader will be called to load paginated list and refresh the viewer.

  4. At this step we can display navigation page with a renderer :

    ResultAndNavigationPageLinksRenderer resultAndPageLinksDecorator = new ResultAndNavigationPageLinksRenderer(parent, SWT.NONE, controller);
  5. At this step, page links are drawn and you can click on page links to navigate to page and refresh the table. Now you can create columns and add sort by adding SortTableColumnSelectionListener to the column:
    TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
    SWT.NONE);
    ...
    viewerColumn.getColumn().addSelectionListener(new SortTableColumnSelectionListener("name", controller));
    

    The constructor org.eclipse.nebula.widgets.pagination.table.SortTableColumnSelectionListener is called with “name” property to sort to Person#getName() property.

  6. Here the full code :

    package org.eclipse.nebula.widgets.pagination.example.table.renderers;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.eclipse.jface.viewers.ArrayContentProvider;
    import org.eclipse.jface.viewers.ColumnLabelProvider;
    import org.eclipse.jface.viewers.LabelProvider;
    import org.eclipse.jface.viewers.TableViewer;
    import org.eclipse.jface.viewers.TableViewerColumn;
    import org.eclipse.nebula.widgets.pagination.IPageLoader;
    import org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper;
    import org.eclipse.nebula.widgets.pagination.PageableController;
    import org.eclipse.nebula.widgets.pagination.collections.PageResult;
    import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider;
    import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
    import org.eclipse.nebula.widgets.pagination.example.model.Address;
    import org.eclipse.nebula.widgets.pagination.example.model.Person;
    import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRenderer;
    import org.eclipse.nebula.widgets.pagination.table.SortTableColumnSelectionListener;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Composite;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Table;
    import org.eclipse.swt.widgets.TableColumn;
    
    /**
     * This sample display a list of model {@link Person} in a SWT Table with
     * pagination banner displayed with Page Results+Page Links on the top of the
     * SWT Table. The 2 columns which display the list of {@link Person} can be
     * clicked to sort the paginated list.
     * 
     */
    public class OneRendererPaginationTableAtHandExample {
    
    	public static void main(String[] args) {
    
    		Display display = new Display();
    		Shell shell = new Shell(display);
    		GridLayout layout = new GridLayout(1, false);
    		shell.setLayout(layout);
    
    		final List items = createList();
    
    		Composite parent = new Composite(shell, SWT.NONE);
    		parent.setLayoutData(new GridData(GridData.FILL_BOTH));
    		parent.setLayout(new GridLayout());
    
    		// Left panel
    		Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
    				| SWT.V_SCROLL);
    		table.setLayoutData(new GridData(GridData.FILL_BOTH));
    
    		// 2) Initialize the table viewer + SWT Table
    		TableViewer viewer = new TableViewer(table);
    		viewer.setContentProvider(ArrayContentProvider.getInstance());
    		viewer.setLabelProvider(new LabelProvider());
    
    		table.setHeaderVisible(true);
    		table.setLinesVisible(true);
    
    		// 3) Create Table columns with sort of paginated list.
    		int pageSize = 10;
    		final PageableController controller = new PageableController(pageSize);
    		final IPageLoader<PageResult> pageLoader = new PageResultLoaderList(
    				items);
    		controller.addPageChangedListener(PageLoaderStrategyHelper
    				.createLoadPageAndReplaceItemsListener(controller, viewer,
    						pageLoader, PageResultContentProvider.getInstance(),
    						null));
    
    		// Create navigation page links
    		ResultAndNavigationPageLinksRenderer resultAndPageLinksDecorator = new ResultAndNavigationPageLinksRenderer(
    				parent, SWT.NONE, controller);
    		resultAndPageLinksDecorator.setLayoutData(new GridData(
    				GridData.FILL_HORIZONTAL));
    
    		createColumns(viewer, controller);
    		// 3) Set current page to 0 to refresh the table
    
    		controller.setCurrentPage(0);
    
    		shell.setSize(350, 250);
    		shell.open();
    		while (!shell.isDisposed()) {
    			if (!display.readAndDispatch())
    				display.sleep();
    		}
    		display.dispose();
    	}
    
    	private static void createColumns(final TableViewer viewer,
    			PageableController controller) {
    
    		// First column is for the first name
    		TableViewerColumn col = createTableViewerColumn(viewer, "Name", 150);
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				String p = (String) element;
    				return p;
    			}
    		});
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				Person p = (Person) element;
    				return p.getName();
    			}
    		});
    		col.getColumn().addSelectionListener(
    				new SortTableColumnSelectionListener("name", controller));
    
    		// Second column is for the adress
    		col = createTableViewerColumn(viewer, "Adress", 150);
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				Person p = (Person) element;
    				Address address = p.getAddress();
    				if (address == null) {
    					return "";
    				}
    				return address.getName();
    			}
    		});
    		col.getColumn()
    				.addSelectionListener(
    						new SortTableColumnSelectionListener("address.name",
    								controller));
    	}
    
    	private static List createList() {
    		List names = new ArrayList();
    		for (int i = 1; i < 100; i++) {
    			names.add(new Person(&quot;Name &quot; + i, i < 25 ? &quot;Adress &quot;
    					+ Math.random() : null));
    		}
    		return names;
    	}
    
    	private static TableViewerColumn createTableViewerColumn(
    			TableViewer viewer, String title, int bound) {
    		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
    				SWT.NONE);
    		final TableColumn column = viewerColumn.getColumn();
    		column.setText(title);
    		column.setWidth(bound);
    		column.setResizable(true);
    		column.setMoveable(true);
    		return viewerColumn;
    	}
    
    }

    Pagination in Table with PageableTable

    You can simplify the previous code by using org.eclipse.nebula.widgets.pagination.table.PageableTable. This explanation is based on the sample org.eclipse.nebula.widgets.pagination.examples.table.OneRendererPaginationTableWithPageableTableExample.

    Here the code which create the SWT Table, the Pagination controller, the TableViewer:

    final PageableTable pageableTable = new PageableTable(shell, SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, pageSize, null,
    ResultAndNavigationPageLinksRendererFactory.getFactory());
    

    This code create the SWT Table, viewer and add on the bottom an instance of ResultAndNavigationPageLinksRenderer.

    PageLoader must be set like this:

    pageableTable.setPageLoader(new PageResultLoaderList(items));
    

    Here the full code :

    package org.eclipse.nebula.widgets.pagination.example.table.renderers;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.eclipse.jface.viewers.ArrayContentProvider;
    import org.eclipse.jface.viewers.ColumnLabelProvider;
    import org.eclipse.jface.viewers.LabelProvider;
    import org.eclipse.jface.viewers.TableViewer;
    import org.eclipse.jface.viewers.TableViewerColumn;
    import org.eclipse.nebula.widgets.pagination.PageableController;
    import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider;
    import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
    import org.eclipse.nebula.widgets.pagination.example.model.Address;
    import org.eclipse.nebula.widgets.pagination.example.model.Person;
    import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRendererFactory;
    import org.eclipse.nebula.widgets.pagination.table.PageableTable;
    import org.eclipse.nebula.widgets.pagination.table.SortTableColumnSelectionListener;
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.layout.GridData;
    import org.eclipse.swt.layout.GridLayout;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.swt.widgets.Table;
    import org.eclipse.swt.widgets.TableColumn;
    
    /**
     * This sample display a list of model {@link Person} in a SWT Table with
     * pagination banner displayed with Page Results+Page Links on the top of the
     * SWT Table. The 2 columns which display the list of {@link Person} can be
     * clicked to sort the paginated list.
     * 
     */
    public class OneRendererPaginationTableWithPageableTableExample {
    
    	public static void main(String[] args) {
    
    		Display display = new Display();
    		Shell shell = new Shell(display);
    		GridLayout layout = new GridLayout(1, false);
    		shell.setLayout(layout);
    
    		final List items = createList();
    
    		int pageSize = 10;
    		final PageableTable pageableTable = new PageableTable(shell,
    				SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
    						| SWT.V_SCROLL, pageSize,
    				PageResultContentProvider.getInstance(), null,
    				ResultAndNavigationPageLinksRendererFactory.getFactory());
    		pageableTable.setLayoutData(new GridData(GridData.FILL_BOTH));
    		pageableTable.setPageLoader(new PageResultLoaderList(items));
    
    		// 2) Initialize the table viewer + SWT Table
    		TableViewer viewer = pageableTable.getViewer();
    		viewer.setContentProvider(ArrayContentProvider.getInstance());
    		viewer.setLabelProvider(new LabelProvider());
    
    		Table table = viewer.getTable();
    		table.setHeaderVisible(true);
    		table.setLinesVisible(true);
    
    		PageableController controller = pageableTable.getController();
    		createColumns(viewer, controller);
    		// 3) Set current page to 0 to refresh the table
    
    		controller.setCurrentPage(0);
    
    		shell.setSize(350, 250);
    		shell.open();
    		while (!shell.isDisposed()) {
    			if (!display.readAndDispatch())
    				display.sleep();
    		}
    		display.dispose();
    	}
    
    	private static void createColumns(final TableViewer viewer,
    			PageableController controller) {
    
    		// First column is for the first name
    		TableViewerColumn col = createTableViewerColumn(viewer, "Name", 150);
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				String p = (String) element;
    				return p;
    			}
    		});
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				Person p = (Person) element;
    				return p.getName();
    			}
    		});
    		col.getColumn().addSelectionListener(
    				new SortTableColumnSelectionListener("name", controller));
    
    		// Second column is for the adress
    		col = createTableViewerColumn(viewer, "Adress", 150);
    		col.setLabelProvider(new ColumnLabelProvider() {
    			@Override
    			public String getText(Object element) {
    				Person p = (Person) element;
    				Address address = p.getAddress();
    				if (address == null) {
    					return "";
    				}
    				return address.getName();
    			}
    		});
    		col.getColumn()
    				.addSelectionListener(
    						new SortTableColumnSelectionListener("address.name",
    								controller));
    	}
    
    	private static List createList() {
    		List names = new ArrayList();
    		for (int i = 1; i < 100; i++) {
    			names.add(new Person(&quot;Name &quot; + i, i < 25 ? &quot;Adress &quot;
    					+ Math.random() : null));
    		}
    		return names;
    	}
    
    	private static TableViewerColumn createTableViewerColumn(
    			TableViewer viewer, String title, int bound) {
    		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
    				SWT.NONE);
    		final TableColumn column = viewerColumn.getColumn();
    		column.setText(title);
    		column.setWidth(bound);
    		column.setResizable(true);
    		column.setMoveable(true);
    		return viewerColumn;
    	}
    
    }
    

    Nebula Pagination API (with Spring Data)

    By default the pagination structure used in the page loader is org.eclipse.nebula.widgets.pagination.PageResult. But it’s possible to use Spring Data pagination structure org.springframework.data.domain.Page with Nebula Pagination. We do that in our Eclipse RCP/RAP XDocReport.
    :

    Before explaining how to use Spring Data with Nebula Pagination, here some interesting information:

    • No need to add Spring dependencies to use Spring Data pagination structure.
    • If you wish paginate :
      • list stored in memory, I suggest to use Spring Data domain Collections.
      • list stored in database I suggest you to use Spring Data JPA or Spring Data JDBC Extensions.
      • If you don’t know Spring Data, I suggets you to study it. You can just write your repository (dao) interface with name convention to manage JPA or JDBC like manage pagination in for Person list:
        Page finadAll(Pageable pagable)

        and that’s all!

    Why Spring Data?

    Why org.springframework.data.domain-only?

    The big problem with Spring Data Core is that it dependends to Spring Core, Spring AOP etc. That’s why we have created org.springframework.data.domain-only which contains only the source of org.springframework.data.domain with pagination structure :

    We have intention to tell about this problem to Spring Data Team and see if those bundles could exist?

    If you wish to manage JPA (like we have done with our XDocReport demo), Spring Data JPA is very helpfull. In this case no need to use org.springframework.data.domain-only because Spring Data JPA requires Spring Core, AOP etc. The only case where org.springframework.data.domain-only is intersesting with JPA is when you have Eclipse RCP client (client side) which calls services with remoting which uses JPA (server side). The client side doesn’t call directly JPA, so no need to have in the Target Platform the Spring Data Core.

    Why org.springframework.data.domain.collections?

    In a business application, pagination is done generally with list coming from database. But sometimes list could coming from java list stored in memory. This is the case for our XDocReport application wich works with DAO layer (Data Access Object) :

    • with JPA (it’s our JPA DAO).
    • or with java list stored in memory (it’s our mock DAO).

For our mock DAO, we need to create Spring Data Page structure coming from a Java list (and not from JPA). Spring Data manages JPA, JDBC but not Java list in memory. The org.springframework.data.domain.collections is able to create Page implementation coming from Java list and Pageable pagination criteria like this :

List persons =...
Pageable pageable =...
Page paginatedPersons = PageListHelper.createPage(items, pageable)

How to use Spring Data with Nebula Pagination?

If you wish use Spring Data Page structure with Nebula Pagination you must add org.eclipse.nebula.widgets.pagination.springdata in your project and :

  • use org.eclipse.nebula.widgets.pagination.springdata.SpringDataPageableController instead of using org.eclipse.nebula.widgets.pagination.PageableController.
  • use org.eclipse.nebula.widgets.pagination.springdata.SpringDataPageContentProvider.getInstance() instead of using org.eclipse.nebula.widgets.pagination.PageResultContentProvider.getInstance().

If you wish use pagination with Java list in memory (and not Spring Data JPA or Spring Data JDBC).

  • use org.eclipse.nebula.widgets.pagination.springdata.SpringDataPageLoaderList instead of org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList.

Pagination in Table at hand

Here the “Pagination in Table at hand” with Spring Data (see org.eclipse.nebula.widgets.pagination.springdata.examples.renderer.OneRendererPaginationTableAtHandExample) :

final PageableController controller = new SpringDataPageableController(pageSize);
final IPageLoader pageLoader = new SpringDataPageLoaderList(items);
controller.addPageChangedListener(PageLoaderStrategyHelper.createLoadPageAndReplaceItemsListener(controller, viewer,pageLoader,	SpringDataPageContentProvider.getInstance(), null));

Pagination in Table with PageableTable

Here the “Pagination in Table with PageableTable” with Spring Data (see org.eclipse.nebula.widgets.pagination.springdata.examples.renderer.OneRendererPaginationTableWithPageableTableExample) :

final PageableTable pageableTable = new PageableTable(shell,	SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, pageSize, SpringDataPageContentProvider.getInstance(), null, ResultAndNavigationPageLinksRendererFactory.getFactory());
pageableTable.setLayoutData(new GridData(GridData.FILL_BOTH));
pageableTable.setPageLoader(new SpringDataPageLoaderList(items));


Angelo Zerr
Angelo Zerr

Eclipse Nebula Picture Control

In some business application, your model (domain) contains sometimes image byte array (ex : photo for person model, logo for project model, etc). In our XDocReport project, we need to manage photo byte array with SWT control for the person model in our Eclipse RCP/RAP XDocReport, in the resume editor :

This last screenshot is the resume editor in WEB context (Eclipse RAP). Here a screenshot in fat client context (Eclipse RCP) :

After several search, it seems that there is no project which provides a SWT picture control, which works with Eclipse RCP and RAP. So we decided to develop SWT PictureControl and give our code to Eclipse Nebula Project with the bug 365948. Today Nebula Team are voting if the project will be accepted or not.

Plug-Ins

Nebula PictureControl contribution provides a SWT control to display an image, remove and modify it. It can be used in the RCP/RAP application context. This control is useful to manage photo, logo in a SWT, RCP and RAP Application. It works with SWT (use org.eclipse.nebula.widgets.picture.PictureControl) and FormToolkit (use org.eclipse.nebula.widgets.picture.FormPictureControl)

The PictureControl contribution zip contains :

  • org.eclipse.nebula.widgets.picture : plugin which contains the Nebula Picture control.
  • org.eclipse.nebula.widgets.picture.example : Main example with PictureControl.

SimplePictureControl

org.eclipse.nebula.widgets.picture.example.SimplePictureControl create a picture control like this :

PictureControl photoControl = new PictureControl(shell);

If you Run org.eclipse.nebula.widgets.picture.example.SimplePictureControl, you will see that :

The “Modify” Link opens the file Explorer View to select an image :

After selecting an image, the image appears :

You can click in the “Delete” link to delete the image. It’s possible to get the image as byte array with the following code :

byte[] imageByteArray = photoControl.getImageByteArray();

When image changes, the PictureControl stores the image as byte array and fires events to tell that image has changed. Here a sample code to observe the image changed :

photoControl.addPropertyChangeListener(PictureControl.IMAGE_BYTEARRAY_PROPERTY,
	new PropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			byte[] newImage = (byte[]) event.getNewValue();
		}
});

This feature can be useful when you wish bind with JFace Databinding the image byte array with a Model object. Here a sample to bind byte[] Person#getPhoto() :

Person person=...;
IObservableValue uiValue = BeansObservables.observeValue(photoControl, PictureControl.IMAGE_BYTEARRAY_PROPERTY);
IObservableValue modelValue = PojoObservables.observeValue(person, "photo");
bindingContext.bindValue(uiValue, modelValue, null, null);

PictureControlWithDefaultImage

It’s possible to set a default image (PictureControl#getImageByteArray() will return null in this case). If you run org.eclipse.nebula.widgets.picture.example.PictureControlWithDefaultImage you will see that :

Here the code to set a default image :

Image defaultImage = new Image(display, PictureControlWithDefaultImage.class.getResourceAsStream("EmptyPhoto.jpg"));
PictureControl photoControl = new PictureControl(shell);
photoControl.setDefaultImage(defaultImage);


Aurelien Pupier
Aurelien Pupier

An effective way to fight duplicated libs and version conflicting classes using Memory Analyzer Tool

In this blog post I suggest a very effective way to spot duplicated libs/classes in your java application. I found and used this tip during the integration phase on an application server – which is quite a common use case.

This tutorial will be very helpful in the following cases:

  • NoClassDefFoundError:  there are two different versions of the same class in your classpath.
  • Integration with unknown huge products (not osgi-ed):  detect multiple libs with the same version, and so reduce memory footprint.

Environment preparation

The first step to do – What? You haven’t already installed it? - is to install the Memory Analyzer Tool (MAT). Then you have to acquire  a heap dump of your running application. These steps are explained in one of my previous blog post.

Easy and effective

Now that you have the heap dump with MAT, you are just three clicks away from spotting those annoying duplicated libs and version conflicting classes.

Go to Open Query browser->Java basics->Duplicated classes:

And here we are – you have the list of all duplicated classes with their classloaders:

Please notice that the class must be already loaded.

A last tip

Since you have made it this far, I will give you another little tip. You can find exactly from which lib the class was loaded using the Inspector view.

For instance, in case the duplicated class was loaded by an URLClassloader, just follow these steps:

  • Select the class;
  • Go to Inspector view in Attributes tab;
  • Right-click on  _context;
  • and finally click go into.

From here look at the attribute _war and you will find from which archive the class was loaded.

Do you have some special tips to use MAT?

Note: this was part of my EclipseCon Europe 2011 talk and one of my Eclipse Democamp Grenoble 2011 talk.

Paul Webster
Paul Webster

maven and tycho vs an Orion feature

EclipseCon 2011 has come and gone, and I was lucky enough to be there.  One of the nice things about going to speak at EclipseCon is the opportunity to see the other projects and technologies congregating around the Eclipse Foundation.  I'll blog later about the talks I gave, but one of the things I tried while down there was using Maven and Tycho to build a p2 repo.

I picked one of the Orion features.  My efforts can be seen in git://git.eclipse.org/gitroot/e4/org.eclipse.orion.server.git in the mavenExperiment branch.

There are some things maven needs to get started, which I put in a parent pom.  A tycho-version property (I needed the 0.11.0-SNAPSHOT so a javax.servlet import package could resolve) and a pluginRepository so I could load that version of tycho.  The repositories to build from: 3 p2 repos in my case.  Some build plugin configuration I copied from the tycho RCP example, including configuring the qualifier with <format>'v'yyyyMMdd-HHmm</format>

The plugin poms are straight forward, as I want manifest first builds.  You just need to make sure the versions and IDs match.  Same with feature poms.

To generate the p2 repo you need to specify 2 things.  An eclipse-repository pom (relatively straight forward, although I've copied in extra maven plugin statements). And a category.xml that lists the features you want in the repo.

I list all of my modules in my aggregator pom, and then run "mvn clean install".

Ta da: a p2 repo with my 2 features in it.

I'm still encountering some problem either with my configuration or with tycho itself.  I open bugs for the $HOME/.m2/repository interfering with a second build: https://issues.sonatype.org/browse/TYCHO-606 and trying to add extra categories to the p2 repo using category.xml results in the generated repo missing things: https://issues.sonatype.org/browse/TYCHO-605

I think there's some work to be done on the Execution Environment side as well, although JIRA appears to be down at the moment.

Once the build has been configured to run with maven, the next person just has to check out the code and "mvn clean install".  That looks promising.  I'm glad I had the opportunity to try out maven and tycho.

Peter Kriens
Peter Kriens

Moving On

A bit more than 13 years ago I was asked to go to Linköping, Sweden to help out an Ericsson business unit to get the Java Embedded Server running on their e-box. This single appointment quickly cascaded into an almost full time job managing the OSGi specification process on behalf of Ericsson. In 2001 I switched to the OSGi Alliance to become the Technical Director and in that capacity the editor

Mike Milinkovich
Mike Milinkovich

It’s Going to be an Exciting Year

Welcome to 2012 folks, its going to be a busy and exciting year. There will be a number of important new projects, programs and initiatives across the Eclipse community. When we’re done Eclipse and the Eclipse Foundation is going to be quite a different – and even more interesting – place. So in no particular order, here is a sampling of some of the big things I see coming.

  • As of the Juno release, Eclipse 4 is going to be the base platform for the Eclipse ecosystem. This means that our download page will only have Eclipse 4.2-based packages. Eclipse 3.8 will also ship as part of the Juno release, but currently there are no 3.x releases planned after that. Although an enormous investment has gone into the backwards compatibility layer for Eclipse 4, it is obviously going to take testing and effort by the Eclipse projects and the many Eclipse adopters to migrate to Eclipse 4.2. So if you haven’t started testing with the Juno builds, now’s the time to start planning for it. Eclipse 4 is a complete re-write of the platform user interface, and brings a lot of value to the ecosystem, including a lot of improved APIs, more flexibility and a refreshed user interface. And its API is 100% binary compatible with the 3.x platform.
  • The migration of the Eclipse community to git is going to be a significant event during 2012. Shutting off CVS in December will be a major milestone. And we are almost done getting the Gerritt code review tool up and running for all Eclipse projects. To make all of this happen has been a ton of work by the webmaster team, the IP team, and you, the community. We’re hoping that using git will make it easier for our community to experiment with, and contribute back to Eclipse projects.
  • A Common Build Infrastructure for Eclipse projects is a new service we plan to provide for projects at Eclipse. It has long been a complaint that getting builds working and running reliably is one of the biggest PITAs in running a project. The goal of the CBI is to reduce that effort, and to provide a core hosted service on eclipse.org infrastructure that all of our projects can use. As part of the initial proof of concept, we’re tackling the toughest build of all: the Eclipse platform. Admittedly, CBI is going to take a lot of work, but we are actively recruiting for a full-time staff member to manage this, and to act as a resource for our project community. This is definitely one of the biggest and most exciting new services we’ve worked on for our committer community. So please get involved, and provide your feedback and your requirements.
  • We will also be launching a new service for members – providing Long Term Support for Eclipse releases. There is a fundamental mismatch between the maintenance window for Eclipse releases and the enterprise products that are built and ship on top. Eclipse release trains at least offer SR1 (September) and SR2 (February) maintenance releases on a regular basis. But an SR2 eight months after a major release is small solace to anyone with a requirement to offer support or maintenance on a product or application for five or more years (as many organizations do).

    As we are rolling this out, it is important to note that the Foundation is not going to be providing support or maintenance directly. Rather, we will work to connect organizations seeking support for Eclipse software with those offering it in order to cultivate a vibrant ecosystem. To help service providers be more efficient and effective, the Eclipse Foundation will provide the infrastructure for the code repositories, bug trackers, build farms, test farms, software signing, intellectual property management, and governance for managing the projects. We will be the trusted organization doing the drudge-work so that others do not have to. In other words, in classic Eclipse style, the Foundation will be acting as an enabler for the ecosystem.

  • Orion is going to ship its 1.0 release later in 2012. There is a ton of work still to do, but there is no doubt in my mind that Orion is an important new technology for the Eclipse community – a whole new tooling platform for the web, in the web.
  • EclipseCon is moving to Reston, Virginia, just outside Washington, DC. We hope to attract a lot of new attendees from the East Coast. In addition to the new location, we’re also adding an entirely new co-conference: Agile ALM Connect
  • And last but not least, we will be creating a number of new Industry Working Groups. IWGs such as Polarsys and M2M are going to be a large focus area for the Eclipse Foundation. But what is an IWG? Basically, they complement Eclipse open source projects with more support from the member companies that are interested in working on them and adopting them.

I see 2012 as a year of significant, and positive, change for the Eclipse community and the Eclipse Foundation. We are certainly not resting on our laurels! I encourage everyone to get involved and contribute to these new initiatives.


Filed under: Foundation, Open Source

David Bosschaert
David Bosschaert

JavaSE 8 Modularity, Project Jigsaw and OSGi

One of the requirements for the JavaSE 8 module system is to provide support for and be able to integrate with OSGi. I am therefore very happy to see that a new OpenJDK project is being proposed to focus on precisely this: Project Penrose. Tim Ellison posted the proposal here: http://mail.openjdk.java.net/pipermail/discuss/2012-January/002320.html

They're still looking for initial supporters, authors and committers, so if you're interested in helping out just sign up!

BTW I posted before on this topic, see here: http://osgithoughts.blogspot.com/2011/05/java-se-8-modularity-requirements.html

January 05, 2012

Vincent Zurczak
Vincent Zurczak

Git, Patches and new Contributors

I have recently committed in the Eclipse BPEL Designer some patches that were contributed in our Bugzilla. This fact itself is not important. However, I used the Git command apply and kept the author name in the commit. I had never used this feature before, but it is extremely powerful. And very convenient to track activities and propose new committers on a project.

I let some traces in this article (as an example and for me, for later).
Notice that the apply command did not work with EGit, I had to use the command line. I guess it will be fixed in a future version.

  • First, we need a patch, given as a diff file, e.g. in a bug entry.
  • As a committer, you should apply and check this patch. So, you first need to copy the patch in your (cloned) Git repository.
  • Get some stats about the patch :
    git apply --stat myPatchFile
  • Make sure the patch can be applied :
    git apply --check myPatchFile
  • Apply the patch :
    git apply myPatchFile
  • Delete the patch file.

Then, you can check that the patch works and then commit it, before pushing the modification.
One important thing is to keep the author’s name in the commit. The author and the committer are different. And both can be kept in the commit and in the history. Here is an example in the command line:

git commit -a --author="authorUsername <author.mail.address@sth.com>"

After the push, both the author and commiter names will appear in the repository.

The author and committer names appear in the history

I don’t know if everyone in Eclipse projects uses this feature, but from the community perspective, this is very interesting (IMO).


Susan McCourt
Susan McCourt

Anatomy of an Orion Page

When we first started building Orion, the site had two pages, a navigator and an editor. Over the course of our release 0.2 development, we grew quite a few pages as we added function. As part of this effort, we worked on the visual design for the pages, with most of that focus being on the overall visual style of Orion and the layout of the header.

Are we anatomically correct?

For our current release, we want to put a "fresh coat of paint" on the pages, but as I've looked at some of our most problematic pages, I've come to realize that we first need to stop talking about things like "headers" and "footers" and start talking about the common, semantic elements that appear on all Orion pages. I'm not talking about HTML elements per se. If we can define and agree on the list of building blocks, then we can talk about how to represent them in the DOM and arrange them visually. The work in progress is documented on the Orion wiki. In this article, I'll describe some insights I've had while working on this anatomy.

In an extensible system like Orion, it's important to think about anatomy vs. layout because we want to allow plug-ins to contribute functionality to existing Orion pages, as well as provide links to pages from another site. When I get a bug report that says, "how can I put a link in the Orion header" or "how can I put a command on the navigator toolbar," I like to ask what the link is for and what is the user workflow, because perhaps that link belongs somewhere else on the page. Hence the focus on anatomy vs. visual layout boxes.

The current list of body parts (no pun intended) is something like this. (The wiki page will be kept up to date with our thinking and explanations of each.)

  • Branding
  • Legalese (the fine print)
  • Discovery links
  • Expected links
  • User Info
  • Notifications
  • Search
  • Task (static page title)
  • Resource
    • Dimensions
    • Hierarchical Location
    • Name
  • Related Task Links
  • Task+Resource (Page) Level Commands
  • Resource View Controls
  • Resource Content

Here's a picture of how these elements might be organized on a page. (Note this is an anatomical picture, I'm not proposing that the Orion header adopt ice cream colors.) Most (all?) sites put the branding on the top left corner and legalese at the bottom, but of course if we stick with semantic definitions when structuring a page, this doesn't have to be true.

Some insights

The body parts that might need some explaining are the ones where I've learned something about our page anatomy and have attempted to use terminology to further qualify an element.

A link is a link is a link?

With links, I find it helpful to differentiate links by thinking about their scope and purpose.

  • Discovery links are there so the user discovers pages that are helpful in the overall site workflows. If you are coding js in Orion, perhaps you'd like to know about "site xyz." (Hmmm....as I type this explanation I realize I haven't mentioned "advertisement" in the anatomy.)
  • Expected links are links you might need to find someday, but you'll expect them and be willing to go looking for it. For example, how do I get support? How do I open a bug?
  • Related task links are links that are directly related to what you are doing. For example, if you are looking at the git log for some repository/branch, it's highly likely you might want to see the git status for that branch.
We also have links that represent commands. These are buttons or links that let you act on a specific thing on the page. But the scopes, placement, and visual representation for these commands will be a future topic, so let's ignore them for now.

A resource by any other name?

Another discovery for me is that it's not enough to talk about "the resource" that a user is operating on. I'm not talking about the page resource/URL, I'm talking about the way the user thinks about the resource they are working with. At a minimum, a resource has a fully qualified (hierarchical) location and a name. But if you add version control to the mix, then you might also want to talk about a particular version of that resource, or perhaps a particular repository. I'm still looking for a better word, but for now I call these dimensions.

Allowing the user to consistently find (and change) dimensions can help the usability of our workflows. Let's take a specific example involving git. Today, in the Orion editor, I can be happily editing my js file. I can even use the breadcrumb to open a navigator within this hierarchy and find related files. But why can't I switch to another branch from the editor? We could hard-code a "switch branch" command into the editor page in the toolbar, but if we instead generalize this idea and have a way to show, and switch, dimensions in a common place on the page, then it will be easier for plug-ins to contribute dimensions and for users to have a common place to go to switch the resource content on the page.

Drilling down

The high level anatomy mentions "Resource Content" but we know there all kinds of ways to represent something, depending on how complex it is. The following terminology helps me talk about the different styles of pages we have:

  • A single content area is appropriate when a resource is best viewed as a unit. The Orion code editor is a good example of a resource that is best viewed with a single content area. Sometimes I think of it as "the real body of the page."
  • Sections organize the view of the resource into separate pieces, so that you can work with different aspects of a resource at a time.
  • Outliners help to navigate a content area. For a single content area, they may simply move the content in a structured way (like the editor outliner). For a resource organized in sections, they may navigate the sections (or help you to swap sections in and out on a page).

By formalizing the sectional nature of pages, we can make it easy in the future for plug-ins to contribute additional sections to a page, provide common places for the user to find commands that apply to a particular section, and common controls for expanding/collapsing or organizing sections.

HTML5: to section or not to section?

When I use the word "section" above I am really talking about a way to organize the viewing and manipulating of a resource. But I didn't want to use that word if it didn't jive with the notion of an HTML5 section. So I checked the HTML5 spec for guidance regarding HTML section elements, and I think this is the right word to use, and that we will end up with HTML5 sections as the tags for these elements on the page. In particular, the spec says, "A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline." That seems to hold up to the way we are using them.

What does this mean to our technical page architecture?

I'm not sure yet, but of course I'll guess.

  • For plug-in developers, we'll formalize our markup surrounding sections and how to describe them in a plug-in. I don't think we'll have plug-ins contributing sections per se in Orion 0.4, but I think we'll start down an implementation path that will make that possible. And we'll probably see a plugin's preferences rendered in a section on the preference page.
  • Inside the Orion implementation, I'd like to see the javascript code talking about the page in terms of tasks and task types, path, name, dimensions, etc. Some common code can map this information to a header (or footer) template, the breadcrumb, etc. If we decide we like combo boxes for changing dimensions one day, and later decide to use drop down menus, it shouldn't be the page's concern at all.
  • Having isolated our javascript code from the common templates, the page implementation code shouldn't even care how the DOM is structured in particular. But long run, it'd be nice to see the Orion page template get simpler, using HTML5 body header, footer, and sections within. Then "something outside the page" (CSS? JS? both?) can apply that to a layout that makes sense for the particular Orion installation, without mandating a particular JS library or approach for making that happen.

What I do know is that in Orion 0.4, it will be easier for you to move between pages in your workflow. And in part, that will because of this anatomy and its corresponding implementation. But while you are using Orion, I don't want you to think about that. Hopefully, you'll just instinctively know how to find what you are trying to do, and think, "wow, these guys always get those links and buttons in just the place I expect them to be!"

Denis Roy
Denis Roy

Authentication changes at Eclipse.org

As you may have heard, we've changed our authentication scheme at Eclipse.org. Instead of having Committer accounts in one database and Bugzilla users in another, both of those databases have been brought together.

We did this for many reasons: it felt strange to ask users to create a "Bugzilla" account to be able to participate on Forums; it was confusing; our sites, such as Wiki and Marketplace, needed to keep track of two auth sources; Eclipse Committers essentially had two accounts, which made no sense; for every new software tool we'd install, we needed to write custom plugins to allow authentication against the Bugzilla database.

Now everything is consolidated, and although we don't have a complete Single Sign On solution, this change has paved the way towards that. It was also a required change in order to deploy the Gerrit code review system.

As with any migration, it wasn't without its bumps and glitches, but overall it went well. Thanks to everyone who tested, re-tested and wrote in to report problems and bugs.

Martin Taal
Martin Taal

Texo: Code Generation Patterns

Texo provides code/JPA entity generation from ecore/xsd models specific for web server/service environments. A main characteristic of Texo is that it separates the Texo/EMF specific generated code from the core entities. This means that generated code can be used directly in other frameworks like ORM’s and GWT without additional runtime layers.

In previous posts on Texo I talked about generating JPA annotated entities, Test-Data generation and generating a DAO layer.

It is very easy to generate JPA annotated entities from an ecore/xsd model using Texo. After installing Texo, right-click any ecore/model and in the Texo submenu choose one of the generate code options.

A next question is how to extend/customize the code generation to fit to specific requirements. In this post I will talk about specific code generation patterns supported by Texo. In a subsequent post I will discuss adding/overriding Texo with your own code generation templates.

Texo supports several different code generation patterns:

  • optional safe bi-directional collection access: resulting in a more extensive (safer) api, but also a bit more complex to understand for many developers
  • list/set: use List or Set for collection instances
  • mix generated and non-generated classes: non-generated classes can be used for eclasses in the model
  • model/framework classes can be generated into a separate package: for runtime model support Texo can generate model-classes, these classes can be generated in separate classes.

All these options are described in more detail on this wiki page.

In addition to the code generation Texo provides a separate runtime layer for XML/XMI serialization, REST webservices etc.

Hope you like it! If you have any questions or remarks please visit the EMFT newsgroup or forum.

gr. Martin


Chris Aniszczyk
Chris Aniszczyk

Help Name Eclipse Juno+1

It’s that time of year, please help choose a name for the next eclipse.org simultaneous release!

There are some interesting options this year, it’s even hard for me to vote:

So, please go vote by January 15th, let’s get a name in time for EclipseCon 2012.

January 04, 2012

Vincent Zurczak
Vincent Zurczak

Enhanced Tabs thanks to ScrolledPageBook

With SWT, tab folders are a way to integrate in a same container several widgets. However, it appears to be quite limited in terms of design and creativity. I here propose some alternatives for sexier user interfaces.

Tab Folder

This is our witness section.
Here is a snippet (the full code is avilable at the end of the article)…

public void createTabs( Composite parent ) {

	final TabFolder tabFolder = new TabFolder( parent, SWT.NONE );
	tabFolder.setLayoutData( new GridData( GridData.FILL_BOTH ));

	for( int i=0; i<=4; i++) {
		TabItem tabItem = new TabItem( tabFolder, SWT.NONE );
		tabItem.setText( "Item " + i );
		tabItem.setControl( createTabContent( tabFolder ));
	}
}

private Composite createTabContent( Composite parent ) {

	Composite c = new Composite( parent, SWT.NONE );
	c.setLayout( new GridLayout( 2, false ));
	String[] properties = { "First Name:", "Last Name:", "Nick Name:" };

	for( String property : properties ) {
		new Label( c, SWT.NONE ).setText( property );
		new Text( c, SWT.SINGLE | SWT.BORDER ).setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
	}

	return c;
}

And here is a screenshot.

An example with a Tab folder

As you can see, everything is centered, except the tabs.
And that’s not cool at all.

Custom Tab Folder

The CTabFolder class is a little more powerful, but similar limitations appear quickly. It is not possible to center the tabs. And they are either above or below the content, never on side.

An example with a CTab folder

public void createTabs( Composite parent ) {

	final CTabFolder tabFolder = new CTabFolder( parent, SWT.BORDER );
	tabFolder.setLayoutData( new GridData( GridData.FILL_BOTH ));
	tabFolder.setSimple( false );

	for( int i=0; i<=4; i++ ) {
		CTabItem tabItem = new CTabItem( tabFolder, SWT.NONE );
		tabItem.setText( " Item " + i + " " );
		tabItem.setControl( createTabContent( tabFolder ));
	}
}

Note that you can add images on the tab.

Scrolled Page Book

An alternative to these classes is ScrolledPageBook.
It can be used in Eclipse plugins, but also in standalone applications. In addition to SWT bundles, you only have to add org.eclipse.ui.forms to your classpath. No need to be in a form to use it.

Let’s see a first illustration, with navigation labels and not (yet) tabs.
The principle is simple: you have a set of labels and a scrolled page book. When the user clicks on a label, we change the displayed page in the book.

public void createTabs( Composite parent ) {

	// Add the container for navigation labels
	final int tabCpt = 5;
	Composite container = new Composite( parent, SWT.NONE );
	container.setLayout( new GridLayout( tabCpt, true ));
	container.setLayoutData( new GridData( SWT.CENTER, SWT.DEFAULT, true, false ));

	// Add the page book
	final ScrolledPageBook pageBook = new ScrolledPageBook( parent );
	pageBook.setLayoutData( new GridData( GridData.FILL_BOTH ));

	// The listener when the user clicks on a "tab"
	Listener listener = new Listener() {
		@Override
		public void handleEvent( Event event ) {
			pageBook.showPage( event.widget.getData());
		}
	};

	// Register the pages and bind it all
	for( int i=0; i<=4; i++ ) {
		Label l = new Label( container, SWT.BORDER );
		l.setText( "Item " + i );
		l.setData( i );

		pageBook.registerPage( i, createTabContent( pageBook.getContainer(), i ));
		l.addListener( SWT.MouseDown, listener );
	}

	// Force to display the first tab
	pageBook.showPage( 0 );
}

And here is a preview.

A first try with a scrolled page book

Ugly, isn’t it?
But we can fix it.

Tabs with a Scrolled Page Book

To have a real tab’s look & feel, we have to reduce the margin between the content and the labels. We also need make our labels look better. Partial borders will be added around the labels thanks to a paint listener.

Tabs with a scrolled page book

Here is the code (it’s a little bit longer than before).

/**
 * Remember the selected index.
 */
private Integer selectedIndex = 0;

/**
 * Creates the tabs.
 * @param parent the parent
 */
public void createTabs( Composite parent ) {
		
	// Add the container for navigation labels
	final int tabCpt = 5;
	Composite container = new Composite( parent, SWT.NONE );
	GridLayout layout = new GridLayout( tabCpt, true );
	layout.marginHeight = 0;
	container.setLayout( layout );
	container.setLayoutData( new GridData( SWT.CENTER, SWT.DEFAULT, true, false ));
		
	// Add the page book
	final ScrolledPageBook pageBook = new ScrolledPageBook( parent );
	pageBook.setLayoutData( new GridData( GridData.FILL_BOTH ));
		
	// The listener when the user clicks on a "tab"
	final List<Label> navigationLabels = new ArrayList<Label> ();
	Listener listener = new Listener() {
		@Override
		public void handleEvent( Event event ) {
			pageBook.showPage( event.widget.getData());
				
			// Remember the last selected index
			TabsWithScrolledPageBookSnippet.this.selectedIndex = (Integer) event.widget.getData();
			
			// Highlight the selected tab
			for( Label l : navigationLabels ) {
				Color color;
				if( l != event.widget && l.getParent() != event.widget )
					color = Display.getDefault().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND );
				else
					color = Display.getDefault().getSystemColor( SWT.COLOR_WHITE );
					
				l.setBackground( color );
				l.getParent().setBackground( color );
			}
		}
	};
		
	// The paint listener, to paint partial borders
	PaintListener paintListener = new PaintListener() {
		@Override
		public void paintControl( PaintEvent event ) {
			
			Color color;
			if( TabsWithScrolledPageBookSnippet.this.selectedIndex.equals( event.widget.getData()))
				color = Display.getDefault().getSystemColor( SWT.COLOR_GRAY );
			else
				color = Display.getDefault().getSystemColor( SWT.COLOR_WIDGET_DARK_SHADOW );
				
			Rectangle rect = ((Composite) event.widget).getBounds();
			event.gc.setForeground( color );
			event.gc.setAntialias( SWT.ON );
			event.gc.drawLine( 0, 0, rect.width - 1, 0 );
			event.gc.drawLine( 0, 0, 0, rect.height - 1 );
			event.gc.drawLine( rect.width - 1, 0, rect.width - 1, rect.height - 1 );
		}
	};
		
	// Register the pages and bind it all
	for( int i=0; i<tabCpt; i++ ) {
		Label l = createTabLabel( i, container, paintListener, listener );
		navigationLabels.add( l );
		pageBook.registerPage( i, createTabContent( pageBook.getContainer(), i ));
	}
		
	// Force to display the first tab (and force it to be highlighted)
	navigationLabels.get( 0 ).notifyListeners( SWT.MouseDown, new Event());
}
	
	
/**
 * Creates a label for the tab (wrapped in a composite for better display).
 * @param index the tab index
 * @param parent the container for the label
 * @param paintListener the paint listener for the label's container (to paint partial borders)
 * @param mouseDownListener the listener for when a tab is selected
 * @return the created label
 */
private Label createTabLabel( int index, Composite parent, PaintListener paintListener, Listener mouseDownListener ) {
	
	// Wrap the labels in a composite
	Composite c = new Composite( parent, SWT.NONE );
	c.setLayout( new GridLayout());
	c.setLayoutData( new GridData( 80, 25 ));
	c.setData( index );

	// To paint partial borders
	c.addPaintListener( paintListener );

	// Deal with the content
	Label l = new Label( c, SWT.NONE );
	l.setLayoutData( new GridData( SWT.CENTER, SWT.CENTER, true, true ));
	l.setText( "Item " + index );
	l.setData( index );

	// The click listener
	l.addListener( SWT.MouseDown, mouseDownListener );
	c.addListener( SWT.MouseDown, mouseDownListener );

	return l;
}

Horizontal Tabs

By playing with the previous example, we can also obtain a result similar to the Eclipse tabbed properties. In the following example, the navigation labels are placed on the left of the content. I hardly changed the code (about 10 lines, it is just about the layout).

Another illustration of tabs implemented with a scrolled page book

The code is available in the archive below.

Conclusion

I hope these snippets (and screenshots) will help some of you.
They also illustrate the use of the Scrolled Page Book class. Obviously, this could be used to create a custom and reusable widget (as an example shared in the Nebula project). No need to say that it would be more simple with a HTML and CSS approach. E4 may help in such an approach.

The complete source code for the snippets is available in this archive.


Philip Wenig
Philip Wenig

Team Project Sets – easy checkout of RCP projects

Recently, some people asked me about a tutorial how to checkout all the needed source code to build OpenChrom from scratch. Meanwhile, it consists of 23 subprojects hosted at SourceForge. Oh my goodness, what have I done the last years – simply call it subproject proliferation. Anyhow, it’s no way to check out all projects by cloning the Git repositories manually and importing the projects into the workspace. Nobody, really nobody want’s to do such a blunt and stupid work.

Once again, Eclipse offers a solution for the problem, and that’s why I love Eclipse sooo much!

Let me give you a short tutorial how to setup OpenChrom absolutely from scratch and how to use “Team Project Sets”.

Install the latest Eclipse IDE “Eclipse for RCP/Plug-in Developers”:
Eclipse 3.7.1 SR1 (Indigo)

Unzip the archive.

Download the Eclipse deltapack**:
Eclipse 3.7.1 Deltapack

Unzip the deltapack and store it in the root folder of Eclipse.

eclipse
  +- about_files
  +- configuration
  +- deltapack **
    +- eclipse
      +- features
      +- plugins
  +- dropins
  +- …

Install the latest Java 7 version (JRE or JDK):
JRE-7 x86
JRE-7 x86_64
JDK-7 x86
JDK-7 x86_64

Start Eclipse and install SWTBot:
SWTBot Update Site

Import all projects utilizing the “Team Project Set”:

OpenChrom.psf (http://www.openchrom.net/main/downloads/OpenChrom.psf)

The process could take a while to import all projects and plug-ins.

Select the appropriate target platform “Eclipse 3.7.1 + DeltaPack”:

Run the product:
Open the file “openchrom.compilation.product” in the plug-in “net.openchrom.rcp.compilation.product” and press the “Launch an Eclipse application” button.

That’s it.
Cheers eselmeister


Sven Efftinge
Sven Efftinge

Collection Literals in Java (or a hidden gem in Eclipse JDT)

Yesterday I watched a devoxx presentation by Joshua Bloch about the Evolution of Java" which I enojoyed.
In that talk he discusses the various language features which have been added to Java in terms of how important resp. problematic their addition was. I agree with most of his reasoning but not with the following two:

  • static imports
    He said they are ok, but not too useful and that he makes use of them only about once a month.
  • diamond operator
    He claimed, that this was an important addition, since now creating new collections is less noisy.

I disagree for the following reasons

Joshua Bloch actually also helped designing a very cool collection library which is part of Google Guava. If you don't know it, have a look! Besides other useful stuff that library contains factory methods for the common collection types.
For instance to create an ArrayList you could write the following:

List<String> names = Lists.newArrayList();

Making use of a static import one can write something like this:

import static com.google.common.collect.Lists.*;
...
List<String> stuff = newArrayList("Foo","Bar","Baz");

But the inconvenience of adding a static import every time you want to create a new collection is a problem. JDT to the rescue! There is an almost hidden gem in JDT, that allows you to have static import favorites for content assist. This is my configuration:



Having your static imports configured here, will make their methods available through code completion without having an import first. Instead the import will automatically be added as you apply the proposal.


I only create collections that way, because it's so easy and readable, and I don't have much use cases for the diamond operator (in fact inference on the left hand side would have been much more interesting). On the other hand I use static imports in almost any class file.

Btw, those static imports not only make the factory methods available but also all the nice higher-order functions like, collect, filter, etc..
A welcome productivity gain!

January 03, 2012

Andrew Niefer
Andrew Niefer

Embedding the Orion Editor

[Edit Jan 3, 2012: Orion has evolved significantly since this post was first written a year ago. Please see this post written by Felipe for an update.]

Yesterday I wrote a blog post which contains a few snippets of Ant code. If you have java-script enabled, those snippets should be nicely formatted with line numbers and some basic syntax highlighting.

Those code snippets are actually being shown using the Orion Editor embedded into my blog post. Granted, using the full editor here is a little over-kill since we aren't doing very much with it, but this was an interesting exercise.

Here is the javascript I wrote to do this:
/*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
function findOrionElements(tagName){
var elements = [];
var tags=document.getElementsByTagName(tagName);
for(var i=0;i<tags.length;i++) {
if(tags[i].getAttribute('name')==='orion') {
elements.push(tags[i]);
}
}
return elements;
}

function createEditors() {
//find all pre elements named 'orion'
var elements = findOrionElements('pre');


for(var i=0; i < elements.length; i++) {
var element = elements[i];

//extract the text from inside the pre
var text = "";
for( var j=0; j < element.childNodes.length; j++ ) {
var nodeName = element.childNodes[j].nodeName;
if (nodeName === "#text")
text += element.childNodes[j].nodeValue;
else if (nodeName === "BR" )
text += '\n';
}

/* Create the editor:
- parent is the containing div element
- readonly by default, but can specify class="writable"
- use the given stylesheet */
var parentNode = element.parentNode;
var elementClass = element.getAttribute('class');
var editor = new eclipse.Editor({
parent: parentNode,
readonly: !(elementClass && elementClass.indexOf('writable') > -1),
stylesheet: "http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/editor.css"
});

// use javascript styler for now, there is no html/xml syntax highlighting yet
var styler = new eclipse.TextStyler(editor, "js");
// add a ruler with line numbers to the left side
var lines = new eclipse.LineNumberRuler("left", {styleClass: "ruler_lines"}, {styleClass: "ruler_lines_odd"}, {styleClass: "ruler_lines_even"});
editor.setText(text);
editor.addRuler(lines);

//fix the height of the containing div
parentNode.style.height = (editor.getLineHeight() * (editor.getModel().getLineCount() + 1)) + 2 + 'px';
}
}


This code is looking for all <pre name='orion'> elements and creating editors to replace them. These elements should generally be contained inside a <div> element. HTML for a replaceable section would look like this:

<div><pre name="orion" class="writable">
var hello = "Hello World!";
alert(hello);
</pre></div>

This example above was made writable by adding "class='writable'" to the <pre/> element. Inside the <pre> element, all '<' should be escaped as '&lt;' and all '>' as '&gt;'.

As a final step, to get this working on blogger.com, I combined my javascript together with:
org.eclipse.orion.client.editor/web/js/editor.js
org.eclipse.orion.client.editor/web/js/model.js
org.eclipse.orion.client.editor/web/samples/rulers.js
org.eclipse.orion.client.editor/web/samples/styler.js
and minified it all using the Google Closure compiler. I hosted the resulting .js file on download.eclipse.org and added the following lines to the bottom of my blog post:

<script type="text/javascript" src="http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/orion-editor.js"></script>
<script type="text/javascript">document.onload=createEditors();</script>


If someone visits the post without javascript enabled, then they don't get the nice formatting on the code snippets, but at least they are still inside <pre> elements which give them some basic formatting.


January 02, 2012

Doug Schaefer
Doug Schaefer

Happy New Year, Out with the Old One.

Surprise! I haven't blogged in a long time (except for the blurbs about the EclipseCon 2012 program, which has turned out great, BTW). There's probably a few good reasons why I haven't spent much time here. The main one, I guess, to quote poor Flyers goaltender Ilya Bryzgalov, I've been a bit "lost in the woods" myself. But like him, that's more a state of mind than fact. And for 2012, I see a few paths that will lead me out of this cloud (or into one which would be one of the paths :).

We lost a lot of great people last year. I'm not sure if it's just my perception because of what happened in my life, but it seems more than usual. For me, it was the loss of my Dad to cancer after a year long battle. He inspired me to live my life with honour and respect for everyone, something which I try to do a lot in my work as the CDT project lead. Communities built based on respect and openness to all comers is the key to success.

Of course, there was Steve Jobs. My wife got me his biography for Christmas and I finished it a couple of days ago. The parallels in his physical condition with my Dad's was amazing. While Steve waited too long to get treatment, my Dad waited too long to get diagnosed and both ended up with their cancer metastasized to their livers which brought about their end. Dad was pretty weak at the end, couldn't eat due to the morphine, but he made one last trip to my dear cousin's wedding where everyone got to see him one last time. Steve was the same and had his last trip to resign as Apple's CEO and had a nice chance to say goodbye. All in all, it's a lesson to take care of yourselves. Treatments are getting pretty good but you got to catch it and act early.

As for Jobs' life and times, I'll dedicate a whole blog article on that. Reading the book was pretty eye opening. I learned a lot about how he really operated and the true reason for his success. And I also got a look into the history and life in Silicon Valley which you don't learn much out here in the wilderness other than the occasional visit. One thing is for sure, I'm pretty sure that life has passed me by and I only regret it a little :).

There were other famous people that passed. Dennis Ritchie being the foremost for me. He doesn't get enough credit for the changes he brought to our industry. Yes, he invented C and helped create Unix, but more importantly, those technologies let average programmers in on the action. Unix machines have always been everywhere and accessible and with their built-in C compiler, you just needed an account to join in on the fun. It's where most of my generation started and why I'm so passionate about the CDT and enabling new generations to learn how to play with fire.

Well, let's stop there for now. I have a lot more to write about and have a new found energy to write about it. I'm hoping this year will be a much better year for me and a great year for you all. Expect to see more in this spot than you have in a long time.

:D

Tom Schindl
Tom Schindl

e(fx)clipse 0.0.11 released

Grrrrr. This now very embarrassing because after i pushed the build to my server and published the release post I found 2 major regressions who make editing fxgraph-Files fairly tedious. I also had a problem with my release script for the 3.7.0 version where I packaged the 0.0.9 version of e(fx)clipse instead of 0.0.10.

So I decided to make another release 0.0.11 which fixes the regression and the packaging. Sorry if this caused trouble to you but this simply slipped through my checks. For those who already downloaded the broken 0.0.10 release I’m sorry but you should redownload version 0.0.11 (it also includes one new feature).

Tooling

FXGraph

Preview Keyword

The keyword has been already part of the language but now its semantics are fully implemented. You can now prefix an attribute in your FXGraph-File with preview and so the content is only passed to the preview but not into the serialized file. I added this feature because sometimes it is necessary to fill controls with data to see how their layout changes. A good example in this sense is the ChoiceBox who layouts itself according to its content.


Tom Schindl
Tom Schindl

e(fx)clipse 0.0.10 released

The 0.0.10 release is broken. Please update to 0.11

3 weeks after 0.0.9 (and one day behind schedule because of New Years day) I just pushed 0.0.10 to http://efxclipse.org/. There are many improvements which will take a look later on and take a look at the provided all in one downloads who’ve been received quite well by the community. In the last 3 weeks I registered the following downloads:

  1. eclipse-SDK-3.7.1-efxclipse-0.0.9-win32.zip: 101
  2. eclipse-SDK-4.2M4-efxclipse-0.0.9-win32.zip: 55
  3. eclipse-SDK-4.2M4-efxclipse-0.0.9-win32-x86_64: 49
  4. eclipse-SDK-3.7.1-efxclipse-0.0.9-win32-x86_64: 41
  5. eclipse-SDK-3.7.1-efxclipse-0.0.9-macosx-cocoa-x86_64: 13

So they are eating up quite some bandwidth (~100GB in December). Let’s now dive into the new features one by one.

All in one downloads

The aim of the all in one downloads has been to give developers an easy way to start writing JavaFX applications. Now that JavaFX is provided as opensource in the openfx-project to give Eclipse users an easy way to contribute I added the mercurial-plugin 1.9.1 to the all in one downloads so that you can access the openjfx-repository without the need to install anything new. I also upgraded to Xtext 2.2.1 and EGit 1.2.0 so that you have the newest bugfixes in your IDE.

Tooling

Internal changes

There are 2 internal changes that happened which you might not directly notice.

SWT-Interop for the LivePreview

One of the internal things I’ve changed was that since 2.0.2 there’s is direct JavaFX-SWT interop available I switched from my hacky JavaFX – Swing – SWT_Swing_Bridge – SWT to it which has 2 consequences:

  • JavaFX 2.0.2 is hard requirement for e(fx)clipse 0.0.10
  • Mac-Support is working and fully supported

JavaFX library look up for the live preview

Until 0.0.9 the look of the JavaFX library for the Live-Preview was done on win32 by consulting the Windows registry and on Mac OS-X by looking for an ENV-Variable (JAVAFX_HOME).

The approach had a draw back because it could have happened that the SDK you had configured in your IDE and the JavaFX version used for the live preview could have gone out of sync. This has now changed and when running inside the IDE the configured SDK version is used instead. This makes it much easier for OS-X users because they now don’t have to reconfigure their ENV to use the live preview.

FXGraph

FXGraph is my custom DSL used to author FXML-Files. I promised that I’ll provide a FXML to FXGraph roundtrip converted but I’ll have to defer this for 0.0.11 or even later.

Support for factory methods

I’ve added support for factory-methods and to really support them I had to change the language a bit which is not a problem because noone could have used this feature because though the language had the keyword for it it was not implemented appropiately.

The syntax looks like this:

New Outline

The outline view in 0.0.9 was the default one provided by Xtext. I’ve invested some time in 0.0.10 to customize it and show informations in a similar fashion the JDT-Outline view does.

Here are screenshots of the results:

Content Assist improvements

The content assist has been improved tremendously by limiting the results to values assignable to the left.

Formatting

The formatting like idents, spaces, line breaks, … have been customized so that you can now press CTRL+SHIFT+F like you are used to in Java-Files and the your source gets formatted nicely.

JavaDoc everywhere

The JavaDoc is now shown everywhere like you are used to it in Java-Files as well. For example when showing the content assist for properties the JavaDoc is displayed next to the proposal.

Autocompleteion for Enum values

Attributes who are represented as enum-Values now provide a content proposal.

Wizard improvements

The wizard has been improved to add support for custom root elements (and remembers them for the next time).

FXML

So in 0.0.9 I switched the FXML-Editor from a custom written to an Xtext backed one (the only feature I had by then was to provide attribute proposals).

So while I also added new features to FXGraph most of the time I spend in this release cycle was on the FXML-Editor front which now has decent sub-element proposals, JavaDoc support, … . The features are yet not as advanced as they are in fxgraph but they are coming along nicely.

Subelement proposals

JavaDoc

Not all elements yet show the JavaDoc appropriate for them but the most important ones already do.

Live Preview

I think that this is the most interesting feature of the FXML-Tooling because it allows you see the resulting UI while you are authoring the FXML-File.

FXML currently does not support to encode custom informations into it because it does not allow one to use itsown XML-Namespace. To make the live preview load the CSS-Files and message.properties one has to add a mapping file in the root directory of the project. The FXML-Wizard will create one for you, if you already have fxml-Files and want to add the configuration-file your own simply create a file named “fxml-preview.properties” in your project (at the toplevel, not inside the src-Folder) and add the following content:

# -------------------------------------
# Configuration setting for FXML-Files
# -------------------------------------

# -------------------------------------
# Values applicable to all FXML-Files
# -------------------------------------

# fxmlpreview.all.stylesheets=test.css            # Comma seperated list of css-styles
# fxmlpreview.all.messagefile=messages.properties # Properties file

# -------------------------------------
# Values applicable to a specific FXML-File 
# (replace ${fxmlfilename} with your filename WITHOUT the fxml-suffix)
# -------------------------------------

# fxmlpreview.file.${fxmlfilename}.stylesheets=test.css              # Comma seperated list of css-styles merged with default styles
# fxmlpreview.file.${fxmlfilename}.messagefile=messages.properties   # Properties file overrules default properties

I think the file is self-explanatory.


Meinte Boersma
Meinte Boersma

New Year’s Resolution: the ASmAP Principle (part 1)

Happy New Year, everyone!

Seeing that we’ve safely progressed into 2012, it’s time for New Year’s Resolutions. As a suggestion for a NYR in software engineering, I’d like to suggest following the

ASmAP-principle, where ASmAP == As Small As Possible

Ever since I started to program on the MSX2, I’ve been wondering where all that extra computing power, memory and disk space that all my subsequent work horses have been endowed with, went to. Obviously, the amount of pixel estate has grown quite a bit (from a measly 0.1Mpixel in 4-bit color to over 1.2 in 32-bit color on the quite modest screen of my MBP 15″), but that doesn’t really explain why my Eclipse typically reports around 200MB of heap space in use: I sincerely doubt that the size of my source code (or even the sheer bytecode size of my compiled classes for a fairer comparison) has grown by a factor of  7000 from the roughly 24KB of memory that was available for MSX BASIC. It also doesn’t explain why whole slews of applications aren’t really more responsive these days than they were in “ye’ olden days”.

Of course, I know that running a JVM and OO languages on it is intrinsically more memory intensive than assembler or what are essentially token streams (the in-memory representation of an MSX BASIC program). But I simply refuse to accept that we need so many more bytes to write even the simplest of programs on our modern-day OSs, VMs and IDEs. I think a large part of this growth stems precisely from Moore’s Law in action: because we have a lot of memory and extra CPU cycles per second, we tend to use them – not per se for more functionality, nicer graphics and such, but also to make programming easier for ourselves without actually delivering more business value or quality.

I’ve seen my fair share of “programming by copy-paste” and the consequences of that: bloated code bases with a lot of (usually inconsistent) duplication, a build process that takes ages to finish and is brittle, a development environment that takes days to set up (possibly after sacrificing a few kittens in the process, just to get it to work at all) and an enormous amount of dependencies (“Maven makes this so easy to manage”) consisting of all kinds of stop-gap frameworks which never seem to solve a business problem and only seem to solve halve of a technical problem. The end result is a gargantuan and monolithic Thing™ that’s hard to fix, hard to alter and hard to hand off to anyone so you’re stuck with it until eternity. Sounds familiar? :)

I think it’s this tendency to copy-paste our way around development, without taking the time to properly Refactor your stuff and reflect on your solutions, which accounts for the enormous gap between a typical application’s footprint and the value it delivers. As a solution, I propose to optimize something that’s relatively easy to measure: the footprint of your code base, in terms of pure source size but also taking into account the amount of re-used “stuff” such as libraries/frameworks, the time needed to build your project and deploy the application and the number of dependencies. In other words: make your project As Small As Possible. (Note that size is a lot easier to quantify than, say, complexity or quality.)

The overruling motivation for doing this is something which hasn’t changed the last few millennia: the amount of information our brains can interpret, process and store (in a limited amount of time). It is this characteristic which is the prime limitation in any project and especially those involving more than one developer – i.e., the typical ones. The amount of information in a software project is a lot bigger than the sheer code size conveys because there are all kinds of connections between various parts of the code base which you need to understand in order to add or change anything in the code. It’s my impression that the complexity is roughly a function of the code size base multiplied by the number of layers/aspects in the architecture.

So, the larger a project’s footprint, the harder it is to understand: not only for your co-workers (who are presumably stupid gits which couldn’t program their way out of a tin can), but even for yourself. The less you understand about your project, the less effective and productive you’re going to be. In other words: you need to build up a mental model of the project (which is something I’ve blogged about earlier) and hope it will fit in your brain in the short time you have. Given that you and your team mates can’t grow extra brains, you’ll have to utilize the available mental processing power as efficiently as possible. Note that adding extra single brains to the project doesn’t provide a solution, because each individual brain will not be able to grok the entire project if you couldn’t do so yourself to begin with.

In the next installment, I’ll discuss some simple approaches to follow the ASmAP-principle.


December 30, 2011

Scott Lewis
Scott Lewis

ECF 3.5.4 and Restlet-based remote services

ECF has just released version 3.5.4. See here for download.

Through our github repo, we now have new OSGi remote services provider based upon Restlet. This allows Restlet to be used as the underlying implementation for OSGi remote services.

The small size and simple implementation of the Restlet-based provider (as well as all the providers) is made possible by ECF's provider architecture. This architecture also allows any transport (rest-based or not) to be easily used to implement any OSGi remote service.

It's probably unnecessary to say, but the use of OSGi services (and remote services), brings many systemic advantages...including built-in support for dynamism, security, version management, modularity, among other things.

December 29, 2011

Tristan Faure
Tristan Faure

Extract relevant elements from a diagram

I would like to introduce in this post a new feature which will be available in the next release of Gendoc2.
This feature makes possible to extract elements you desire in a diagram.

This example will generate a part of the UML Metamodel documentation.
The diagram realized with MDT Papyrus is presented bellow:

This diagram displays some information about Events, Activity Nodes and Operations. For the documentation we only want to display the elements linked to the Signal Event and the Call Event meta classes.

This is now possible using new methods in TOPCASED and GMF bundles.
This is the code to use in your gendoc2 template :

  1. The diagram is get using getPapyrusDiagrams() method
  2. A list of visibleElements is computed using a focused class (SignalEvent or Call Event)
    • [let visibleElements : Set(uml::Class) = Set{focus}->union(focus.superClass)->union(focus.superClass->closure(superClass)->union(focus.getAssociations().memberEnd->select(type <> focus).type->asSet()))]
  3. The list of visible elements is used by the getDiagram method
  4. Finally the elements visible in the diagram are listed and for each element the documentation is displayed
The result is visible bellow