Friday, August 31, 2007

Almost there, mom...

Yet another month has gone and my perfect plan to blog about something cool in EMF every week didn't work as intended. If you check the date of my last post, you will see that it was written right on the last day of July. And here I am, last day of August...

Being honest, I can't even say that I've been busy doing development work. Other than a few bug fixes and time assisting users, most of my (and Dave's) days have been spent on the second edition of the EMF book. The good news is that we are really almost done writing the manuscript. And the material is looking great! We took the time to go deep on several topics and also to add much more content than what is available in the first edition. Just to give you an idea, the second edition will be at least as thick as the first one and it doesn't have the not so popular "javadoc" chapter.

Btw, if you were intrigued by the title... I was naive enough to tell my family and close friends about the book when we've started working on it, a looooong time ago. So now I am often hearing the inevitable question "when will it be available" regardless of where I am: at work, conferences, and, unfortunately ;-), BBQs, bars, ...

Tuesday, July 31, 2007

No more NPE when generating models

For most users, EMF 2.3 is all about Java 5.0. Although most of our time was certainly spent on Generics and other "5isms", we sure managed to implement a few nice features as listed in our release notes. BTW, I know that this report is not as beautiful as a "New and Noteworthy" page, but that's the best we can offer now. Note to Wassim: I promise we will try to improve for this release ;-)

Of these nice features, the one I think I like the most is the complete validation of Ecore models. Basically this work consisted on defining and implementing all the constraints that characterize a well-formed model using the EMF Validation framework. Without an automated way to check these constraints, aka "before 2.3", any poor soul manipulating Ecore models would probably end up getting all sorts of exceptions when generating the code for the models. In face of these exceptions, the users would do the simplest thing available at the time: post a question on the newsgroup and wait the excruciating 10 minutes delay that usually takes Ed to answer.

Now this has changed! To check if your model is correct, hence capable of being used for code generation, all you need to do is to either open the .genmodel file editor or, on the .ecore file editor, select a package and run the Validation action available in the context popup-menu. Any existing problem in your model will be then presented in a tree viewer, with (hopefully ;-) all the information you need to have it fixed.

I should mention that EMF 2.3 can validate any Ecore model. So even if you are using an older version of EMF and usually edit your Ecore models directly, I believe the model validation justifies having the 2.3 release installed somewhere in your machine.

Thursday, June 28, 2007

I want my feature request implemented yesterday!

"What do you get when you put together a bunch of passionate developers and a code freeze policy due to the end of a release?" This is probably a good start for a Dilbert cartoon. Certainly Scott Adams' answer would be brazilian times funnier than mine, which is "crazy people implementing the cool things they want regardless of how beautiful the day is outside".

The "cool thing" I worked on yesterday was to leverage the pattern filter widget you see on Eclipse's New Project Wizard to some EMF dialogs. After some digging I was able to get the results I was looking for by simply using new FilteredTree(...).getViewer() instead of new TreeViewer(...). BTW, I would recommend reading the PatternFilter's Javadoc if you are considering doing the same in your code.

Everything was going smooth up to the moment that I've opened a subclass of org.eclipse.ui.dialogs.ElementTreeSelectionDialog. I couldn't believe what I was seeing: there was no way to replace the TreeViewer used by this class. Profoundly disappointed, I began to write a feature request for the UI team. As I was doing it, I thought that I would be a much better Eclipse citizen by providing a patch instead of simply describing what to do. So I checked out the "org.eclipse.ui.workbench" bundle, opened ElementTreeSelectionDialog, and added a new protected method that instantiates the TreeViewer. Before changing the line of code that would use my new method, I looked around to see how the Javadocs on the file are written. To my surprise I discovered this new method: ElementTreeSelectionDialog.doCreateTreeViewer(Composite, int). After blinking my eyes for a few seconds I realize that the method I need is already available in Eclipse 3.4. Amazing!

Kudos to the UI team.

Tuesday, June 26, 2007

EMF tips and tricks: Don't save if it hasn't changed.

For a while I have been thinking about writing some EMF tips that may not be known by most of the users. What keeps me from doing it is the lack of inspiration to come up with a nice introduction and to explain the rationale behind a design. This is probably silly though. I am sure I would be way more useful if I simply focus on showing the "what" and "how", leaving the long discussions for the cases when someone is actually interested ;-)

So here we go...

We've added a few new options to the EMF Resource in EMF 2.3 (the one available in Europa). One of them is Resource.OPTION_SAVE_ONLY_IF_CHANGED. When this option is used, the save method writes out the bytes of the serialized objects only if these bytes are different from the existing persisted form of the resource. Behind the scenes, the objects in the resource are serialized to either a temporary file or memory buffer and then compared with the bytes read from the URI pointed to by the resource. Clearly this slows down the save operation, but it may be useful when, for example, the resource serializes to a file that is versioned by CVS, hence avoiding "zero delta" changes.

This snippet shows how to use this option:

Map<Object, Object> saveOptions = new HashMap<Object, Object>();
saveOptions.put(
Resource.OPTION_SAVE_ONLY_IF_CHANGED,
Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
resource.save(saveOptions);

Using OPTION_SAVE_ONLY_IF_CHANGED_FILE_BUFFER instead of OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER would serialize the objects to a temporary file instead of using a buffer in memory. This subtle difference is important when dealing with big resources.

An experienced EMF user may be asking how this relates to the Resource.setTrackingModification(boolean) method and to the "dirty" state of the editor generated by EMF. The main difference here is that the new option applies to the actual bytes of the serialized resource while the other two approaches are related to the state of the objects in memory. For example, the new option doesn't change the serialized resource when a "dummy" modification is made to an object (such as setting an attribute to its current value), but would do it if the serialization format changes (which could be caused by using a different value for the XMLResource.OPTION_LINE_WIDTH option, for instance). The other two approaches do the exact opposite in these examples.

Friday, June 8, 2007

From iterator-loop to foreach-loop with one regex.

Probably the most important feature we've worked on this release was to add Java 5.0 support to EMF. We've learned a lot during the process and actually had some fun trying to make sense out of Generics and Annotations. Of course there were also some very annoying tasks, such as converting Java 1.4 "Iterator loops" into the new "foreach loop" style. For example, this snippet

for (Iterator i = Collections.singleton(new Integer(1)).iterator(); i.hasNext();)
{
Integer integer = (Integer)i.next();
System.out.println(integer);
}

should look like this after the modifications
for (Integer integer : Collections.singleton(new Integer(1)))
{
System.out.println(integer);
}

Unfortunately Eclipse's "Source->Clean..." magic action doesn't do a good job here since it doesn't keep the names and types of the "each" variable. At least back in December, I would end up with Object object : instead of Integer integer : for the example above.

Either to boost my productivity or just to exercise the right to be lazy ;-), I've come up with a regular expression that does the conversion for me. It works flawless with Eclipse's Find dialog (ctrl+f):



Here's a clipboard friendly version:
Find:
(for\s*\(\s*)Iterator\s*\w*\s*=(.*)\.iterator\(\).*;\s*(\)\s*\{\s*)(.*)\s*=.*next\(\);\s*

Replace with:
$1$4:$2$3

Monday, June 4, 2007

I can't see the code I blog!

Today I was proudly showing my blog to Dave, a good friend from work. "Proudly" would be the perfect word if it also meant "embarrassed". While I consider myself an illiterate in multiple languages (after 7 years in Canada I haven't learned English yet and my Portuguese is starting to fade away), Dave is my "English hero". Not only he writes really well but also knows all the grammar rules that would explain "why one should use a comma here" for example. A typical case of knowing what to do and how to do it. Anyways, I am digressing...

When I was showing the blog to Dave, he pointed out that the chunks of code I wrote were not been properly displayed on his Windows box. After some digging, we found out that the culprit was the "fixed" font on my CSS. After changing it from

font-family: fixed, courier, courier new, times, times new, times new roman;

to
font-family: courier new, courier, fixed,  times, times new, times new roman;

everything worked just fine.

Perhaps I should show this to Nick, another good friend from work, from whom I've stolen... err... leveraged the CSS customizations.

Friday, June 1, 2007

EMF? O que é EMF?

Geralmente quando leio algo sobre o EMF em Português, acabo aprendendo alguma coisa sobre MyEclipse ou VE. Pelo visto o pessoal ainda não descobriu o poder deste componente, tratando-o apenas como mais um incômodo detalhe de instalação.

O EMF, do qual sou desenvolvedor, pode simplificar drasticamente o desenvolvimento de aplicações Java (a serem rodadas no Eclipse ou não). A partir de uma especificação de um modelo (em XML Schema, por exemplo), com apenas alguns cliques, é possível gerar um editor no Eclipse capaz de criar e manipular instâncias deste modelo. Por trás das câmeras, o editor utiliza outro código Java, também gerado pelo EMF, que implementa as classes definidas no modelo. Em outras palavras, se o modelo diz que uma Biblioteca tem Livros, o EMF vai gerar algo parecido com

public class Biblioteca
{
List<Livro> getLivros();
}

Este código é completamente independente do Eclipse, podendo rodar em qualquer ambiente Java. A propósito, Java 5 é opcional.

O EMF pode fazer muito mais que simplesmente gerar código para classes. Espero ter tempo e, porque não, incentivos em forma de perguntas e encorajamentos, para escrever, em Portuga, algumas dicas.