lunes dic 19, 2005

RSS: One stylesheet to rule them all?

Bloglines and RSS parsing

As you probably know I've been exploring Bloglines services to easily build just another RSS reader. The fact is that I have found no services to handle channels. This is, you cannot programmatically add/remove/update channels. Too bad. :-(

So, unless I'm completely wrong, we'll have to parse RSS ourselves.

First approach: Rome

The very first approach is, of course, Rome, Sun's open source project for RSS parsing.

But, to be honest, Rome is too big for my liking, too powerful for my modest needs. It depends on JDOM (which, luckily, seems to depend on nothing else). Rome is very good to parse in detail all sort of RSS flavors. All I want it to have a least common denominator of different RSS flavors. RSS 0.91, RSS 0.92, RSS 1.0, RSS 2.0 and Atom 1.0 would be good enough, I think.

Furthermore, I'd like to do it myself so as to exercise Java XML APIs. After all I need to keep up with those things, it's some sort of hobby of mine ;-).

SAX Parsing: the cost of speed

So my very first approach was to go for speed, using SAX parsers. I've built a SAX handler that is chained with other different SAX handlers for every different flavor of RSS.

And, to be honest, the thing works quite fast. SAX parsers consume little memory and run really fast.

But after all the experiment those SAX handlers looked to me quite similar to AWK scripts. This is: they're difficult to maintain. I don't think I'll be able to modify those RSS handlers myself within, say, one month from now.

XSL to the rescue?

So I thought, why not use an XSLT stylesheet to extract information from those different RSS flavors (RSS 0.91, 0.92, 1.0, 2.0, Atom 1.0) and transform those different flavors in a least common XML file? Then with a single SAX parser I'd be able to parse all sort of RSS flavor.

And, since all transformation is handled in a XML file (the XSLT stylesheet) it should be easier to maintain. Of course there's a cost for this ease of mainteinance: we're loosing speed.

I'm sort of tired now (it's difficult to write coherently, sorry by that), but I think a small diagram could explain things better. There we are:

I've been doing some tests and, well, there's some lack of speed. But I think it's worth the effort. Simpler, smaller, easier to maintain, no dependencies... I like it.

What do you think? Any suggestions? Any way to improve the XSLT stylesheet? (By the way, the XSLT stylesheet can be found here).

Cheers,
Antonio

jueves nov 17, 2005

Bloglines is cool

Live from Sevilla. Foggy this morning, but lots of sun in the afternoon!

Someone suggested buildling an RSS Feed Reader/aggregator as a sample Swing application, just to experiment with different ways to organize the model, the view and the controller.

And, since I don't really like any RSS feed readers around, I thought it could be a good idea.

The fact is that, as in Jonathan's case, I need a high mobility RSS feed reader. I switch computers all the time, so I need to store my preferred RSS feeds somewhere in the Internet. I can't rely on a local hard disk, either.

So I happened to pass by bloglines and I noticed their excellent REST services. Really cool. They keep all your RSS feeds for you, and cache them, and then allow you to retrieve them using a simple HTTP call.

And that's exactly what I need. They provide a simple RSS storage mechanism for me. For free. They keep all my RSS feeds there. And, more interestingly, they parse them for me. They worry about RSS 0.91, RSS 0.92, RSS 1.0, RSS 2.0, Atom 1.0 and whatever-the-version-is version and parse them for me. And they produce clean RSS 2.0 instead.

So I think that it may be a good idea to build a Swing rich client application that consumes bloglines REST services.

That rich client application could then be stored somewhere in the Internet. And, being downloaded using JNLP, I could then have a truly mobile RSS feed reader.

Cool.

Greetings from Sevilla,
Antonio

viernes nov 11, 2005

Let's get it organized

What a week, dude. Lots of things to do. Little time for funny activities. And the coming one is even worse, much more traveling (back to Sevilla again). I'll try to post some photos of Sevilla and the "tapas" they have there.

The fact is that I've received different emails through my blogging alias. Apart of omnipresent spam I've received a couple of mails asking about the event bus, and about the organization of the model, the view and the controller in Swing applications.

Let's get organized

So I thought it could be a good, illustrative idea to show different ways to organize things in Swing applications. Different ways to architecture the internals of a GUI application.

And, before going any further, I thought it could be a good idea to ask you all what you think of this. Say I am to write an application using the Presentation Model paradigm, and then rewrite it using the Model View Presenter approach. And then rewrite the first one using an event bus, and do the same with the second one. Something like this:

  • Presentation Model, no event bus.
  • Model View Presenter, no event bus.
  • Presentation Model, event bus.
  • Model View Presenter, no event bus.

(Any other suggestion is, of course, welcome).

And then, after watching those four, see how things could be further improved. Or even write a comparison of them all. Some sort of guidelines for choosing which one better fits your needs.

So, my questions is, is it worth the effort? What do you think?

Doing what?

The application should be useful, of course. I suggest doing some sort of easy to use bookmark manager. Since I use different computers I have different set of bookmarks in different places. I'd like to store those in, say, Google's gmail (as a plain jar file, say). Any other ideas about useful (little) applications are welcome, too.

Thanks for any ideas and have a restful weekend (I will ;-)),

Antonio

viernes oct 21, 2005

Domain Models, Value Models, Swing Models

The fact is that blogging requires time. And if you're short of time then you don't blog well. You don't explain yourself. You don't get understood. And, since blogging is about explaining yourself, then you fail as a blogger.

That simple. That difficult.

And I think that's what has happened with my latest posts. Someone has warned me about it. Thanks for that. If it ever happens again, if I ever don't explain myself, then just ask. Please warn me about this. After all this is an interactive place. Don't be afraid to criticize or just complain! That's part of being interactive! ;-)

So I'm trying to connect the model to the bus. The idea is that whenever the model changes then events are generated and sent through topics in the bus to the view (that is responsible for painting them).

And this, although easy to explain in a few lines of blogging, is quite difficult to do in practice. Before rushing into the code I like doing some research. After all, that's the fun part of this! So please let me explain what I'm looking at, let me share that with you, just in case you want to add any idea!

Models: domain models, value models, Swing models

So, how many kinds of models are there? What do we mean by model? What's the "model" in the "Model-View-Controller" paradigm? What is a domain model? What a value model? How do Swing models (DocumentModel, ButtonModel and ListModel) relate to those? Why is Laura Ponte such a great model? (Oh, well, just because she's galician too? :-D )

Most of these questions are answered at the Swing Data Binding Framework by Karsten Lentzsch (well, Karsten doesn't talk about Laura Ponte, sadly ;-) ).

To be honest, Karsten's binding framework is the most interesting framework I've seen around for handling the model in a Swing application. Well, in fact is the only framework I know of for handling the model. Or do you know of any other out there?

Let me explain what I understand of it (and what I don't) and why this binding framework (that has been around for some time) is so interesting to me.

Domain models

(Many different definitions here, I'll try to explain my preferred one. I know there're different versions and definitions, but the following one is good enough for the purpose of this blog. I wouldn't like to discuss on this ;-) ).

Domain (object) models represent a conceptual vision of a system. The types of objects your software will be dealing with. The objects you design to deal with a business problem. Class diagrams or entity-relationship (ER) database diagrams are usually good enough to visualize domain models.

Of course, you want your domain models to be independent of the user interface. Domain models usually live in the business tier, whereas the views live in the presentation tier. And even when your application is not multi-tiered, you still want to separate them. To reuse your domain in another applications (or to exploit your domain model from different user-interfaces, such as a command line and a GUI).

For an example of a domain model you can see this image taken from this article at The Server Side.

As Karsten's explains in his article, Domain models can be built with plain Java Beans (Plain Old Java Objects or POJOS). I have to agree. Java Beans is the easiest way to do it. Having a Domain Model designed as a set of POJOs is simple, is serializable (can be persisted to the disk or to an object oriented database) and, if you use bound properties, you can have Observers listen for changes on the domain model. (And that's exactly what I want to do with an event bus, for instance).

But as Karsten's nicely explains in his article, it's probably not a good idea to make your view depend directly on your domain model. (That's what he calls "Direct Adapters", the reasons why this is not a good idea are explained in slide # 43 in his article).

A similar thing happens in J2EE applications. Usually in J2EE applications you make your domain object model persistent using Entity Beans, DAOs, JDO, Hibernate or a mix of those. The "conceptual vision of the system", the domain model, can then be persisted in a database. But when building J2EE applications you don't really want to make your view depend directly on your domain model. You prefer to use the Transfer Object Core J2EE Pattern in your servlets and JSPs. (If you're not familiar to Transfer Objects you can think of these as a small photograph of a part of your model). You also want to use View Helpers, and different other J2EE patterns in your view.

Value Models

So how to avoid the problem of making your view directly depend on your domain model?

Well, of course, by using an indirection. Make your view depend on something, say Value Model, and then make that (the Value Model) depend on your domain model. You've got the indirection. There's no (direct) dependency. Problem solved. This Value Model is explained in slide #44 of Karsten's article.

And that's the way a (nice) J2EE application works too. Make your views depend on your transfer objects, and make these be a (partial) copy of your domain model. Make your views depend on business delegates, but not on all the internals of your business tier.

Introducing indirections between two parts of your software makes dependencies between these controllable. Allows you to build a single point of contact, a logical frontier between tiers. Keeping the indirection under control means keeping the dependency under control.

If this indirection layer is correctly built then things are easier to maintain. What is interesting about Karsten's binding system is that this indirection layer seems to be correctly built. He uses a "universal model" (ValueModel) to separate the view from the domain model (see slice #47 for details on the ValueModel). So the view has to deal with a single type of objects: ValueModels. And not with the specifics of the domain model you're building. Views become reusable. Views become isolated from the domain model. And this simple concept makes things easier when building Swing applications: the domain model is focused in the business problem and the view is focused in correctly handling ValueModels, whatever they contain.

From domain to value models (to SwingModels)

So how to transform domain models to value models while keeping them in sync? As Karsten's suggests: by using BeanAdapters and PropertyAdapters (slide #52). These "adapters" listen the domain model for PropertyChanges. Whenever a property changes in the domain model the change is automagically transformed into a change in the ValueModel, and viceversa. Easy to do. Reflection as needed. The powerful java.beans.\* package into action.

There're several issues with this approach, namely avoiding syncing before the user presses an "OK" button, or handling lists and table models. Karsten keeps on explaining these issues in the following slides. Check his article for further details on these.

Karsten explains as well how to make different SwingModels use ValueModels. There're adapters for these. Again check his article for further details.

From domain to value models: by bus??

So why talking about all these models here? How do they relate to an event bus?

Well, if you go take a look at Karsten's article, at slide #54, you'll see something like this:


private void initComponents() {
  Album album = getEditedAlbum();  // 1
  ValueModel aValueModel =
    new PropertyAdapter( album, "classical" ); // 2
  JCheckBox classicalBox = new JCheckBox();
  classicalBox.setModel( 
     new ToggleButtonAdapter( aValueModel ) ); // 3

So what this basically says is that in order to initialize the views of your components you have to get a reference to the domain model ((1) Album here) and then build a ValueModel from it (2) and then build your GUI with the ValueModel (3).

Note that your GUI components (classicalBox) need only a reference to the ValueModel, and may be completely isolated from the domain model. What I mean is that you don't need your domain model to compile your GUI. You could refactor the code above and remove completely the "Album" class by hiding it in another class. By using some sort of ValueModel factory or something.

What I really mean is that you could do something like this:

This is, make your domain model notify changes using the bus. Let me try to be more specific: instead of writing


ValueModel aValueModel = new PropertyAdapter( album, "classical" );

(which means: create a new ValueModel that is notified whenever the property "classical" in "album" changes) use the bus to rewrite the view as:

// Create a new value model
ValueModel aValueModel = new ValueModel();
// That is notified of PropertyChangeEvents whenever
// an event is received through the "album.classical" topic
bus.addEventListener( aValueModel, "album.classical" );

and rewrite the domain model as:
// Get a reference to an Album in your domain model
Album album = ...
// Make the "album" bean send PropertyChange events when
// properties change. 
// When the "setClassical()" method is invoked on the Album bean
// then a PropertyChangeEvent will be sent through the
// "album.classical" topic in the bus
bus.addEventSource( album, "album" );

So you completely isolate your view from your domain model. You can make them change independently. You don't need domain models to compile your GUI (just ValueModels).

So that's what I'm investigating now

So that's why I've been writing about Java Beans and PropertyChangeEvents and PropertyChangeSupport lately. I am trying to build a suitable domain model using just plain JavaBeans. Plain POJOs.

And I will like to reuse Karsten's binding library to attach things to the bus. After all I think Karsten's binding library is the most comprehensive mechanism to tackle the model in Swing. Or is it not? Do you know of any other framework/library to do it? What do you think of this? Do you think it appropriate or just too complex?

Am I following the KISS principle? Or do you think this is too elaborate just to use models? (This is, shall I continue this or not?).

As always all feedback is greatly appreciated.

Have a good weekend,
Antonio

lunes oct 17, 2005

Apt models

Extremely busy weeks behind (and probably ahead too) so I've been unable to post anything interesting for a while. Sorry by that.

I am currently thinking on how to better build the models for Swing applications.

And, of course, I'm thinking of annotations ;-)

JavaBeans for me, please

I would like to build models using JavaBeans (Plain Old Java Objects, or POJOs, say). I would like each property of my JavaBeans to automatically generate PropertyChangeEvents for me.

Of course that's not very difficult to do. I could use java.beans.PropertyChangeSupport to do that.

Let's see an example. Let's say I want to model a Person with two properties: full name and email. I could build a JavaBean like this:


package com.sun.antonio.models;

import java.beans.\*;

public class Person
  implements java.io.Serializable 
{
  private String fullName;
  private String emailAddress;
  private PropertyChangeSupport pcs;

  public Person()  { pcs = new PropertyChangeSupport(this); }

  public String getFullName() { return fullName; }

  public void setFullName( String aFullName )
  {
    String oldName = fullName;
    fullName = aFullName;
    pcs.firePropertyChange( "fullName", oldName, fullName );
  }

  public void addPropertyChangeListener( PropertyChangeListener pcl )
  {
    pcs.addPropertyChangeListener( pcl );
  }
  // removePropertyChangeListener and get/set EmailAddress below removed
}

The code above is simple to write. I could use a java.beans.VetoableChangeSupport too, to add support for vetoable changes. (If you need more information on JavaBeans or bound properties or constrained properties you may want to read more on the topic).

But although simple to write (and to read) it requires too many lines of code. I'm too lazy to do that donkeywork. I'd prefer using a shorter, more compact notation for defining my JavaBeans.

And, although I don't really like code generation stuff, I thought of using a code generation mechanism to generate my JavaBeans.

The incredible autogenerated JavaBean

The very first approach could be, of course, XDoclet JavaBean tags.

So I thought of downloading and setting up XDoclet on my wonderful NetBeans 5.0 Beta. But then I thought that it could be a good idea to use something similar to JAXB 2...

The incredible XML mapping

I happened to pass by Kohsuke Kawaguchi's Blog where I could read:


@XmlRootElement
class Point {
  @XmlElement
  public int x;
  @XmlElement
  public int y;
  Point(...) { ... }
}
Hey! He was defining the XML mapping of a Java object in Java using annotations. This is cool!.

I wanted to do that, too. What about writing something like this?


@JavaBean
class Person
{
  @Property( type=BOUND ) private String fullName;
  @Property( type=CONSTRAINED ) private String emailAddress;
}

This is, I could define a JavaBean annotation and a Property annotation so that classes and attributes marked with these could be used to generate the code I had to write by hand at the top of this entry. Those annotations could automagically create PropertyChangeSupport and VetoableChangeSupport for me, and fire appropriate PropertyChangeEvents when required (on the setter methods).

The idea seems to be interesting. What about this?


@JavaBean
@XmlRootElement
class Person
{
  @XmlElement @Property( type=BOUND ) private String fullName;
  @XmlElement @Property( type=CONSTRAINED ) private String emailAddress;
}

This is, if I use annotations for JavaBeans I can mix these with JAXB2 annotations, so that all my model can be persisted to XML too.

But using annotations for JavaBeans seems to be nothing new. See, for instance, damnhandy's blog on ideas on how to do this.

Apt models

One of the nice things about annotations is that you can generate both source code and class files from them using the apt tool. I'm experimenting with it right now. Maybe I'll post some examples here.

And, well, NetBeans, of course...

Since building an APT based tool to generate JavaBeans seems a little bit too elaborated to me, I thought of building a NetBeans plugin.

And, well, the fact is that... none is needed!!! NetBeans has already a built-in command to do it. It generates PropertyChangeSupport for me (or even VetoableChangeSupport). And takes all the hassle of hand-writing property change listeners and firing property change events.

Since this is a little bit hidden feature, I think it's better to show the process with some screenshots.

First of all I create a plain Java class as usual (File/New/Java Class). And call it, say, Person.

Then I open the class in the Project Window until I can see the "Bean Patterns" node. Like this:

Then a dialog appears. In this dialog you can choose what type of property you want to create (plain, bound, constrained). The nice feature is that NetBeans automagically creates a PropertyChangeSupport for you.

The generated code looks like this:


  /\*\*
   \* Utility field used by bound properties.
   \*/
  private java.beans.PropertyChangeSupport propertyChangeSupport =  new java.beans.PropertyChangeSupport(this);
  
  /\*\*
   \* Adds a PropertyChangeListener to the listener list.
   \* @param l The listener to add.
   \*/
  public void addPropertyChangeListener(java.beans.PropertyChangeListener l)
  {
    propertyChangeSupport.addPropertyChangeListener(l);
  }
  
  /\*\*
   \* Removes a PropertyChangeListener from the listener list.
   \* @param l The listener to remove.
   \*/
  public void removePropertyChangeListener(java.beans.PropertyChangeListener l)
  {
    propertyChangeSupport.removePropertyChangeListener(l);
  }
  /\*\*
   \* Getter for property fullName.
   \* @return Value of property fullName.
   \*/
  public String getFullName()
  {
    return this.fullName;
  }
  
  /\*\*
   \* Setter for property fullName.
   \* @param fullName New value of property fullName.
   \*/
  public void setFullName(String fullName)
  {
    String oldFullName = this.fullName;
    this.fullName = fullName;
    propertyChangeSupport.firePropertyChange("fullName", oldFullName, fullName);
  }
Which is good enough for me, just with a few clicks.

Conclusion

So, although generating JavaBeans with apt (or xdoclet) may be a cool feature, I think I'll stick with NetBeans at the moment. The generated code is excellent and, well, the feature is already integrated in my favourite IDE.

Anyway maybe I'll come back to annotations in the future to generate code... What about a @TableModel annotation that automagically generates a TableModel for you? What about a @ListModel one? And, of course, are you using annotations for your model? Would you like to? What do you think of using the APT tool to generate source code for your Swing applications? (Any ideas/rants/complaints are, of course, welcome).

(Note to NetBeans team: you've earned a free beer whenever you happen to visit Madrid).

Happy modelling,
Antonio

UPDATE:

It seems Core Java II vol. II (Chapter 13) has some examples of APT Annotation Processors to build BeanInfo (I don't own Core Java II yet, I think I should go buy it, right?) Sample code here.

martes oct 11, 2005

Annotations, dynamic proxies and talking models

Since it's a long time since my last (interesting) post I thought I could give you all a little update on the current status of affairs. What I've been reading and how things are going.

I'm receiving comments and email from many of you. Let me comment on (some of) these. And let me talk again about the bus driver.

Annotations, what for?

Ingo (who is currently writing his master thesis, good luck, Ingo!) has asked me why and where do I want to use Annotations for the event bus.

Well, to be honest annotations are not really needed at all. You can use plain old listeners for event handling.

But although not neccessary they may be useful. Let me briefly explain why I think they may be of interest.

Handling events in Swing is easy but, from my point of view, requires lots of code. You have to create a listener, whether anonymous or not, and then make the listener do what you want. And then remove it in case of need. That requires several lines of code. We can make things easier (note that writing less code is not always a good idea if you write less legible code. But discussing that will require another entry ;-) ).

Easier event handling I: dynamic proxies

One way to make things easier is by using Dynamic Proxies. These "Dynamic Proxies" are a way to build classes dynamically (i.e., while the application is running) that implement some interface you want. Say you have an ActionListener interface. You can dinamically build an object (a dynamic proxy) that intercepts all calls to methods in the ActionListener interface. So when someone calls the method "actionPerformed( ActionEvent ae )" the dynamic proxy will intercept that call. Then you can do whatever you want there. Say send the ActionEvent to a bus of events, for instance.

The small UITopics implementation we talked about earlier just does this. It dynamically builds listeners for those interfaces you want and redirects all events there to a topic in the bus. So the call:


JButton myButton = ...;
TopicManager tm = ...;
tm.addEventSource( myButton, "mybutton.events", ActionListener.class, MouseListener.class );

(If you're new to UITopics just think that TopicManager is a weird, unappropiate name of the Event Bus).

That code builds two proxies, one that intercepts calls to all methods of ActionListener and another one that intercepts calls to all methods of MouseListener.class. And then redirects all events to the "mybutton.events" topic in the TopicManager.

To clarify. The code above is rougly equivalent to this:


JButton myButton = ...;
TopicManager tm = ...;

myButton.addActionListener( new ActionListener() 
{
  public void actionPerformed( ActionEvent ae )
  {
    tm.sendEvent( myButton, "mybutton.events", ae );
  }
} );

myButton.addMouseListener( new MouseListener() 
{
  public void mousePressed( MouseEvent me )
  {
    tm.sendEvent( myButton, "mybutton.events", me );
  }
  ... // idem mouseReleased, etc.
  public void mouseClicked( MouseEvent me )
  {
    tm.sendEvent( myButton, "mybutton.events", me );
  }
} ();

Note that the three lines above using dynamic proxies are equivalent much more lines using normal listeners.

Using dynamic proxies for event handling is a very old technique. More info can be found at java.sun.com and www.javaworld.com (1999).

Easier event handling II: annotations

The second way to make things easier in event handling is by using annotations. Since dynamic proxies are built dinamically for building listeners, why not take advantage of annotations to dinamically (too) define how listeners expect events to be received?

UITopics uses annotations to define how listeners want to receive events. From which topic, and on which thread. That makes things easier to code.


@TopicListener( topicName="mybutton.events", isAsynchronous="true" )
public void myMethod( TopicManager tm, ActionEvent ae )
{
  ... // asynchronously handle ActionEvent
}

Note that by using dynamic things you (may?) loose strong typing. Applications may fail at runtime if these are not correctly tested. By using dynamic things you make things easier to develop at the expense of static (compile-time) safety (you've been warned ;-)).

There's an interesting article on using annotations for event handling at JavaWorld. Note that the article is dated October 2005. As you can see things are moving in this field. The article contains interesting ways to annotate listeners. (Interesting ideas for the bus, too).

Event driver revisited: is it MVC or MVP or PM or what?

In my last post I suggested we could use the model to send events to the views through the bus. I am still digesting one of the latest (Aug. 2005, PDF, English) of Karsten Lentzsch's articles entitled "Desktop Patterns and Data Binding for Swing". You may know Karsten because of all JGoodies goodies (including the Looks Look and Feel, his Binding and Validation and tons of other good stuff).

Karsten is one of my gurus. Reading his articles is always interesting. That one of Aug. 2005 is also interesting. He shows the differences between MVC, Swing MVC, Model View Presenter (MVP) and the Presentation Model.

I like Model View Presenter. I like hearing that "MVP holds the GUI state once", whereas "PM holds it twice".

For further reading you can see a nice description of MVP or even see how to build an application using MVP. Note that

It is much cleaner to design and build the core of the system, the domain model, first and then to add the user interface classes subsequently.

I agree. I think we all do. The model should be the bus driver.

Listen: the model is talking

So, if the model is so important, how should the bus listen to it? If the model is changed, how is it supposed to notify the bus? Which topics/channels/interrupt levels should be updated? How should we name them? What is the easiest way to do this?

Most Swing models talk themselves:

  • javax.swing.Document talks javax.swing.event.DocumentEvents to javax.swing.event.DocumentListeners.
  • And javax.swing.tree.TreeModels talk javax.swing.event.TreeModelEvents to javax.swing.event.TreeModelListeners.
  • (include the Swing model you want here)

So one way to plug-in these events to the bus is using Dynamic Proxies as well. Dynamically building event listeners that automagically redirect the events to the bus. The first approach could be:


TopicManager tm = ...;
javax.swing.Document document = ...;
tm.addEventSource( document, "document.events", DocumentListener.class );

As we did above with components. The code above will make the model redirect all DocumentEvent's from the given document to the "document.events" topic. Make your Swing components listen to these topics (using the actuators we talked about earlier) and you're done.

But, is there any easiest way to connect the model to the bus? A different way? Simpler? More effective? ...

Talking beans?

... I think there is, but I'm not sure if this is a good idea or not. Let me explain it to you and please provide feedback on it.

Imagine you build your model with Java Beans (i.e., POJOs; also known as Value Objects or Transfer Objects). You may use a PropertyChangeSupport to fire property change events whenever you "set" any property in your bean.

Using PropertyChangeSupport and firing property changes is way more easy, from my point of view, that building custom events (DocumentEvent, TreeEvent, ListSelectionEvent, etc.) and listeners and the methods used to work with those (fireDocumentEvent, etc.).

Now, wouldn't it be interesting to attach those Java beans to the bus? What about adding PropertyChangeListeners to the bus and using the property names as a suffix for topic names? We could use the property names as part of the topic name.

Take for instance you have a "Person" JavaBean that models your user data. Say that the "Person" JavaBean has two properties: name and lastName. The idea is to attach "Person" to the bus on topic "user" and have the "setName()" and "setLastName()" automagically send PropertyChangeEvents through the "user.name" and "user.lastName" topics.

Summary and next steps

So in this post I've explained a way to attach objects to the bus. Event sources (such as Swing components, macro-components or the model) can be attached to the bus using dynamic proxies. Event listeners can be attached to the bus by using annotations. More work is needed to find a set of interesting annotations. As Tim suggested in previous comments, we could explore SYNC, ASYNC, SYNC_SWING, ASYNC_SWING for threading.

In the coming weeks (I'm too busy right now with different customers) I'll try to experiment how well the model is being attached to the bus (using those PropertyChangeSupport objects). Always trying to make things simple.

After that, once the model can be easily plugged into the event bus, I think we could experiment on threading and vetoing.

Any ideas, critics and suggestions are, of course, welcome.

Happy swinging,
Antonio

lunes oct 03, 2005

About the bus driver

Spot the difference!

What's the difference between these two figures?

Which one do you think is the correct one? Which one do you prefer?

Well, if we try to follow the Model-View-Controller paradigm, then:

Controller: This responds to events, typically user actions, and invokes changes on the model (but \*not\* the view).

So it seems that the second one is the correct one. It's the model that notifies the view about any change, and not the controller handling the view directly. (Of course that's the way things are done in Swing, so that approach is possibly more intuitive than the previous one, right?).

So I propose being the model that pushes events into the bus whenever it is changed. The model should drive the bus. Actuators will then receive these changes and update the views accordingly.

The flow of events would then be as follows:

  • 1. Macro-components generate events, that travel the event bus using topics.
  • 2. Controllers receive and coordinate these events, and modify the model accordingly.
  • 3. The model fires events when changed, and these travel through the bus using (one or more?) topics.
  • 4. The actuators are updated of changes and update the view accordingly.

Opinions on this? What do you think?

Since I'm afraid this is getting too academic let's see things by example.

Opening files

Let's assume the user wants to open a file.

  • 1. The user selects "File/Open" in the menu (or in a toolbar) and an ActionEvent is generated from the menubar (toolbar) through the "menubar.events" or "toolbar.events" topics in the bus.
  • 2. A controller is connected to both the "menubar.events" and "toolbar.events" topics and asynchronously reads the file and creates a javax.swing.text.Document for the file.
  • 3. The controller updates the model inserting this javax.swing.text.Document in the model (possibly in the Swing thread). Once the model is updated it generates a DocumentOpenedEvent event through the "model.documents" topic in the bus.
  • 4. There're different actuators listening on this "model.documents". The "MenubarActuator" will insert an entry in the "Recently opened" menu. The "EditorActuator" will open a new editor tab and include the new javax.swing.text.Document in an EditorPane. The "StatusBarActuator" will update the message in the status bar indicating that the file was opened.

Note: if there's an IOException in step 2 above then steps 3 and 4 are not executed, but instead:

  • 3. The controller updates the model inserting an Exception in the model's "errors" list. Once the model is updated the model itself generates a "ApplicationErrorEvent" through the "application.errors" topic in the bus.
  • 4. There're different actuators listening on this "application.errors" topic. The StatusBarActuator, for instance, will show a red label with the error.
Note there's no veto here: the controller detects the error and generates an event.

Another example: closing the application

  • 1. The user selects "File/Exit" in the menu (or clicks on the close window button in the window) and an ActionEvent is generated from the menubar (or a WindowEvent is generated). These events travel through the "menubar.events" or the "window.events" topics in the bus.
  • 2. A controller is connected to both the "menubar.events" and "window.events" topics in the bus.
  • The controller checks the model to see if all files are closed. If not then it will ask the user (in the event thread) if he wants to quit without closing. If the user selects "YES" then the controller updates the model indicating that the application has to be closed. If the user selects "NO" then the controller does nothing.
  • 3. If the application has to be closed then the model fires an "ApplicationQuit" event through the "application.control" topic.
  • 4. The "ApplicationActuator" releases all resources used by the views, closes and disposes all windows.
Just one more example before continuing...

Another example: saving

Let's assume the user wants to save a file.

  • 1. The user selects "File/Save" in the menu (or clicks the save button in the toolbar). An ActionEvent is generated from the menubar (or an ActionEvent is generated in the toolbar). These events travel through the "menubar.events" or the "toolbar.events" topics in the bus. li>2. A controller is connected to both the "menubar.events" and "toolbar.events" topics in the bus.
  • The controller asynchronously saves the document (contained in a javax.swing.text.Document in the model). And then updates the model indicating that the document is saved.
  • 3. When the document in the model is saved an "DocumentSavedEvent" is sent through the "model.documents" topic.
  • 4. There're different actuators listening on this "model.documents" topic. The "MenubarActuator" will disable the save menu (because the document is saved). The "StatusBarActuator" will set a message indicating that the document was saved.
What about errors? If there's an error saving the document in step 2 then the model won't be updated and steps 3 and 4 above will not be executed. The behaviour could be similar to the one when opening the file above.

Vetoing and threading

Note that in the examples above there's no need to veto events: it's controllers who are responsible for handling errors and unsaved situations, so all the hassle about handling vetoing in different threads just dissappears. Again, I can't think of a situation where vetoing is strictly needed (any ideas here would be appreciated).

I think we need more brainstorming for the threading issues. Let's say we accept the model as the bus driver. The one that rules actuators. Then that's probably a good hint on how threading should work. The model should be modified by a single thread, I suggest. So probably the easiest thing to do is to use the EDT as the one responsible for modifying the model. So all events to actuators should be genereated in the EDT. That's probably the easiest thing to do, right?

State machines

I keep on thinking of state machines in the background. Sorry I can't resist! Interesting things I've found about state machines for GUIs and that need further investigation:

I think the next step could be to modify the demo application to make the model drive the bus. Don't you think?

Thanks for any suggestions,
Antonio

miércoles sep 28, 2005

Free bus tickets for everybody

First of all I'd like to thank everybody for taking the bus. It's all of you that are making this a fascinating trip!.

After that I'd like to say that everybody has a free ticket for this bus. SWT, GTK, QT, wxWindows and even MFC and .NET developers have a free ticket for this bus. This for free for everybody. Although we're focused in a Swing implementation; you can probably apply it to your favourite GUI toolkit, whether GTK or SWT or whatever.

Finally if you have trouble with written english then puedes hablar español (yo haría la traducción al inglés si tengo tiempo), podes falar galego se queres, ou podes tentar falar portugués (eu tentarei façer uma traducção) (I'm not very good writting portuguese, though).

Vetoing and threading

As Nascif clearly explained, the problem with vetoing is that the caller thread blocks waiting for feedback on the event. If the caller thread is the Swing thread (as it is in the current implementation of many buses out there) then the Swing thread blocks. And that's a problem: the whole GUI will freeze. One solution that comes to my mind is making the whole event dispatching through the bus in a dedicated thread (Tim has suggested this too, I think). Nascif has also re-introduced the idea of state machines.

As Tim has nicely expressed vetoing is useful for easily handling error conditions. You send the event to the macro-components and you're able to see if the thing worked or not. Take for instance: you send a save action and wait to see if the data was actually saved (or if, on the contrary, an IOException was generated and the data could not be saved). In order to alleviate the thread-wait problem Tim has also suggested sending feedback on success by using an state topic.

(Well, I don't know if I'm giving credit to everybody correctly, but you can check yourself in the comments section for the previous post).

What I think is a problem with event vetoing is delivering the same event through different actuators/mediators in different threads. In the actual implementation of UITopics you may send an event to topic listeners in different threads (either in the Swing thread or on a worker thread). In the curent implementation it's the topic listeners who are responsible for deciding if they want to receive the event in the Swing thread or in a worker thread. Now, invoking different topic listeners in different threads and waiting for an exception to be thrown (or any other mechanism of vetoing) may be somewhat hard to do.

Anyway I'd like to introduce GASM and ASML2 before going any further. I've done some little research and found GASM by accident (Google helping ;-) ). I think it's worth a look before deciding about vetoing and threading.

State machines under discussion... or not?

Different people have suggested using state machines. After all, since controllers just receive and send events... couldn't they be programmed as state machines? Now, isn't it worth to evaluate how difficult writting state machines in Java is? Isn't it worth evaluating it now, before deciding on vetoing? Isn't it that vetoing is just a fork/join in a state diagram? I'm sure you all agree. Let's be open-minded to different alternatives and, after seeing as many as possible, let us agree on a final decission.

So I've found GASM. GASM is defined as "A Formal Method for Specification and Verification".

Wow. The "Formal" adjective looks a little bit scary, doesn't it?. "Formal" is usually related to complex things. Maths are formal and are usually difficult to grasp. But "specification" and "verification" sound good. I think I'd like my big Swing application to be as verified and specified as possible.

So I entered the GASM Introduction and found that GASM has the following desirable characteristics: precision, faithfulness, executability, scalability, generality and understandability (quoting: "ASM programs use an extremely simple syntax, which can be read even by novices as a form of pseudo-code").

Now, that is interesting. "Extremely simple" and "novices" and "pseudo-code" sound good. Maybe this "formal" thing is not too complex after all.

So I kept on reading a little bit more and found that Microsoft research has already defined an Abstract State Machine Language v2.0 that seems to be implemented in .NET. Quoting:

"It is an executable specification language based on the theory of Abstract State Machines. The current version, AsmL 2 (AsmL for Microsoft .NET), is embedded into Microsoft Word and Microsoft Visual Studio.NET"...
Well, it seems lots of people are working on ASML as a way to formally verify software. It seems Microsoft is embedding powerful state machines in complex GUI software. That's a hint. After all Microsoft Word is a huge GUI application. I think we all would like our big Swing applications being formally verified. Right?

So, my final questions (and sorry to just keep doing questions all the time). Shall we go take a look at state machine implementations out there? Give the a try? Or is this just out of scope and we should concentrate on the event bus instead? If defining a state machine in another language but Java, which language should it be? SMC's FSM language (compiled to Java)? Or an interpreted language such as JPython, XML, Groovy or Scheme?

I'd appreciate any opinions, suggestions and critics. I'm getting too confused ;-)

Thanks in advance,
Antonio

P.S.: There's no problem in using JDK 1.4. Annotations could be substituted in some way using reflection or other mechanisms when adding/removing topic listeners. The only requirement I can think of is using Doug Lea's concurrent utilities (adopted in JDK 5.0 as java.util.concurrent).

P.S.II: Hierarchical listeners: Shouldn't be too difficult to do, I think. What about keeping a topic-listener map in a SortedMap and then using submap to fetch a subset of the map? (The "trie" or "Patricia Trees" data structures could be of help here too, that way you could fire events to "\*action" or "file\*", this is, by using either suffixes or prefixes).

martes sep 27, 2005

The bus, from the plane

Before rushing into the actual implementation I'd like to show you a 10000 feet view of the bus. Just in case you want to give some feedback/suggestions. What I am thinking of is something like this (click to enlarge):

So basically there're three parts:

  • View: formed by the macro-components and, possibly, some "actuators" (more on this later).
  • Controller: formed by the mediators. Contains the business logic. Has read/write access to the model. Receives events from the components through the bus (component-events), through specific topics (XXX-event). Sends commands (application events) to the bus through specific topis (XXX-command) Does not contain any instances of the view.
  • Model: formed by data (current clipboard contents, currently selected file, whatever).

So what I am thinking of is something like this:

  • 1. Components send components through their specific topics towards the controllers.
  • 2. Controllers coordinate component events. May veto (discard) events depending on the model. Controllers may modify the model.
  • 3. Controllers create and send application events (commands) through specific channels in the bus. These events are business specific and need not be related to components.
  • 4. Actuators receive application components from the bus and modify the view accordingly. These actuators are the only responsible for holding instances to components.
From my point of view controllers are what we've called "Type II aggregators" (no instances to the view, no dynamic dependencies) whereas actuators are "Type I aggregators" (instances to the view, dynamic dependencies).

(Well, I hope I've made myself clear. If not then just email me!)

Doubts, design decissions, help appreciated

  • Vetoing. Shall we need actual vetoing of events? I think it's enough if controllers just ignore/react to events depending on the model. Can you think of an example where I could need vetoing for events? Tim, any idea about this?
  • No component-controller dynamic (runtime) dependencies. With the approach above I think we have dynamic decoupling of components and controllers. What I mean is that we don't need macro-components instantiated before controllers are instantiated. If components are absent then there's no problem for controllers. Controllers may be instantiated independently of components. This is right I think (am I right here?)
  • Component-controller static (compile-time) dependencies. In order to compile the controllers I'll need to have component events in place. This is, there's a static dependency between components and controllers. I don't think this is an issue, unless you need to compile controllers and components independently. I can't think a reason why these static dependencies are an issue. Any scenarios you can think of?
(Diagrams are here, OpenOffice/StarOffice, 9Kb, right-click/Save As... to download).

Thanks for any ideas!
Antonio

lunes sep 26, 2005

By bus or... on foot?

So I've been receiving some mails with some questions and suggestions. And, to be honest, I'm confused. Too many ideas. Brainstorming is working!!

Some of the ideas were about the site design. I've taken some into account (a friend of mine helped me with the HTML, well, that's difficult!). Expect some more changes in the coming weeks as time permits. Entries are more organized now in (hopefully useful) categories. I've also included some links to other interesting blogs, too. Feedback is greatly welcome.

So I decided to share with you my concerns, just once more, in order to try to clarify things. (So, please, help me here).

There we go:

Question I: Is this "Event Bus" a new "pattern" or not?

Someone suggested this "event bus" approach was some sort of pattern. I've been reviewing the "Observer Pattern" in my copy of "Design Patterns" during this weekend. And reading Design Patterns I've found interesting stuff I'd like to share with you. Just to try to clarify my thoughts.

Let me quote Design Patterns just a moment, please:

"Define a one-to-many dependency between objects so that when one object changes state (our macro-components), all its dependents (listeners) are notified and updated automatically"

D'oh!! One-to-many what?? Dependencies, you say?? Wait, wait, wait. Wasn't it "Find dependencies... and eliminate them"?? Isn't that the problem? Yes! The Observer Pattern is the problem! The macro-components of my Swing applications (the Observables/Subjects) keep "one-to-many" dependencies with the listeners (the Observers).

That's why my StatusBar is a listener of the FilesystemViewer, and the FilesystemViewer is a listener of the Menubar! And the Editor is a listener of both the FilesystemViewer and the Menubar! And that's why I'm having chains of listeners, and thus chains of dependencies. And that's why I'm having so many problems with large Swing applications!!

So let's define a new pattern!! Let's call it the Event Bus Pattern!! Pretty much as Martin Fowler calls it an Event Aggregator.

Well, er... no.

That would be just plain Overpatterning, I think. Isn't it?

Let's keep on reading.

Please allow me to quote here an excerpt of Design Patterns. Again. Please bear with me.

Encapsulating complex update semantics. When the dependency relationship between subjects (macro-components) and observers (listeners) is particularly complex, an object that maintains these relationships might be required. We call such an object a Change-Manager (i.e., the Event Bus equivalent). Its purpose is to minimize the work required to make observers (listeners) reflect a change in their subject (macro-components). For example, if an operation involves changes to several interdependent subjects (macro-components), you might have to ensure that their observers (listeners) are notified only after all the subjects (macro-components) have been modified to avoid notifying observers (listeners) more than once.

Design Patterns - Implementation, paragraph 8

So, as you can see, the Event Bus was already defined as early as 1994!! (Well, I think the "Change-Manager" is not exactly an Event Bus because the one-to-many dependencies are still kept there between Subjects and Observers, but it's a rough approximation, thoughts?).

But, wait, there's even more. Go see section Implementation.7 and you'll see aspects defined, something similar to "topics", "interrupt-levels" or "channels". Isn't it? (Or is it that I see topics everywhere? ;-) )

But, wait, wait, there's even more!!

At the end of section Implementation.8 I read:

... ChangeManager (EventBus) is an instance of the Mediator pattern. In general there is only one ChangeManager, and it is known globally. The Singleton pattern would be useful here.
(Note that ELF is using singletons for their event bus).

So, as you can see, Mediators were already in place in Event Buses in 1994!!

Question II: Is this "event bus" really needed for big Swing apps?

Jim asked if this "event bus" approach is required for big Swing applications.

This is, shall we go by bus or just on foot with simple Listeners? I'd say this "event bus" is not needed, but may be helpful (what do you think?) (In the sample application there's an asynchronous listener for logging events to System.out, for instance, and building it is extremely easy).

Typical medium-size Swing applications have usually some sort of controller. Usually mixed with view logic. You can see an example in the Mandelbrot Explorer source code. Take a look at the MandelbrotViewController.java class. That's a ZoomListener, ShiftListener, PropertyChangeListener and ProgressPaneCancelListener. All in one. It aggregates events from different views. And then it coordinates them. It's a mediator instance.

But by doing things through "event buses" you may make things easier. It's easier to encapsulate these "mediators" in separate classes, attached to the bus. Don't you think?

Question III: Aren't we generating tons of events?

Well, it depends. Don't you generate lots of Actions? I'd say Swing "Actions" encapsulate event listeners, right?. Actions tend to be more powerful "ActionListeners". So, what about changing Swing actions into, say, ApplicationEvents through the bus? EditAction, OpenFileAction and the such would then be transformed into EditActionEvents, OpenFileActionEvent or, as Tim suggested, EditCommandEvent, OpenFileCommandEvent.

So, from my point of view, yes: it generates lots of events. But that's not a problem, I think. Thoughts?

Example

UITopics demo Screenshot

I'm almost done with the sample application (JDK5.0 Java Web Start). I'll talk of it in the coming weeks as a basis for discussion. It's built with Type I aggregators (controllers with instances to the view). Source code is available (uitopics and JDK5.0 required).

I think mediators (package net.java.uitopics.demo.controllers) are not that difficult to read, right? Any suggestions?

Cheers,
Antonio

viernes sep 23, 2005

Take the bus yourself!!

So you may want to take the bus yourself and see how well it goes.

Note that this is an alpha version and I'm still experimenting with it (I'm working out a demo). I'd suggest you generating javadoc.

It's just six classes, but don't panic! Of those six just two are public (and one of them is not a class but an annotation).

This is one of my Type I aggregators:


public class StatusMessagesMediator
{
  private Statusbar statusbar;
  public StatusMessagesMediator( Statusbar aStatusbar )
  {
    statusbar = aStatusbar;
  }
  @TopicListener( topicName="filesystem.events" )
  public void onFilesystemEvent( TopicManager aTopicManager, FilesystemEvent anEvent )
  {
    switch( anEvent.getEventType() )
    {
      case FilesystemEvent.SELECTION_TYPE:
        statusbar.setStatusMessage( anEvent.getFile().getName() );
    }
  }
}

To attach the mediator (aggregator) to the bus just write:


StatusMessagesMediator mediator = new StatusMessagesMediator();
topicManager.addTopicListener( mediator );
To attach a macro-component to the bus just write:

FilesystemViewer viewer = new FilesystemViewer();
topicManager.addEventSource( "filesystem.events", viewer, FilesystemEventListener.class,
  ActionListener.class, (any other EventListener class here)... );
(Note that you specify listener types and not events, sorry).

I decided to post it here just because the java.net project is still under approval (maybe they're surprised it's just six classes ;-) )

During this weekend (if time permits) I'll think about building a Type II aggregator using a Type I aggregator. (Hint: split the aggregator above into two ones. One with instances and another without instances, change topic names, done?)

Sorry for the short post (I'm in a hurry now). Enjoy it. Have a good weekend. Keep Swinging,
Antonio

Traffic lights for the event bus

Wow! This is warming up. Thanks all for your comments, emails, and for taking the bus with me!

There're lots of interesting things in your comments so I'll try to review them all, as time permits, and express what I think. So please correct me if I'm wrong. Get ready for one of the biggest blog entries in the Internet! (Sorry by that :-()

Event Buses and Event Queues

As Kevin points out there're similarities between event buses and the AWT Event Queue. After all, let's be honest, both are ways to deliver events to listeners!

In fact I think that taking control of the event queue may be of great help in GUI development. It allows you to be asynchronous. It allows you to take control on event delivery. I've taken a look at foxtrot (as you know foxtrot is a well known framework for handling asynchronous operations in Swing) and found that... they're taking control of the event queue too!! See:

In contrast, Foxtrot lets the Event Dispatch Thread enter but not return from the listener method, instead rerouting the Event Dispatch Thread to continue dequeuing events from the Event Queue and processing them. Once the worker thread has finished, the Event Dispatch Thread is rerouted again, returning from the listener method.
But, wait, there're many more examples out there! As Jonny (thanks, Jonny, I didn't know about it!) kindly pointed out we have the Event-Listener Framework (ELF), too.

So it seems taking control of the event queue is key to ease things. Taking control of the event queue seems a powerful idiom. Now, what is the difference between an event bus and a controlled event queue? Don't they both deliver events?

Well, as far as I understand, the main difference may be explained with this drawing...


   +---------------+ +----------------+ +-------------+ +-------------+
   |               | |                | |             | |             |
   | ActionManager | | EventResponder | |  AntModule  | |  AntModule  |
   |               | |                | |(ProjectNav) | |(SourceEdit) |
   +---------------+ +----------------+ +-------------+ +-------------+
           |                  \^               \^               \^
           |                  |               |               |
      ActionEvent         EventObject      AntEvent       AntEvent
           |                  |               |               |
           v                  v               v               v
  /---------------------------------------------------------------------\\
 /                                                                       \\
<                                   EventBus                              >
 \\                                                                       /
  \\---------------------------------------------------------------------/
           |                  \^               \^               \^
           |                  |               |               |
      EventObject         ChangeEvent      BuildEvent     EventObject
           |                  |               |               |
           v                  |               |               v
   +---------------+ +----------------+ +-------------+ +--------------+
   |               | |                | |             | |              |
   |   Console     | |  ProjectProxy  | |    Ant      | | (Your Module)|
   |               | |                | |             | |              |
   +---------------+ +----------------+ +-------------+ +--------------+

... that I've copied (without permission!! ;-)) from the antidote design document (antidote is a GUI for Apache's ant).

This is, I think that the event bus delivers events the same way an event queue does, but it's the single point of contact between components. Or, as the Antidote design document nicely explains:

"In order to keep the coupling among application modules to a minimum, a single point of reference is needed for coordination and data sharing."
(Note that this is exactly what ELF does, too).

Topics, Channels and ... interrupt levels!

Note as well that the Antidote design document describes different topics (or channels) to deliver events. They call them "interrupt levels".

If you read carefully you'll see a VETOING topic, a MONITORING topic, and a RESPONDING interrupt level. Now, don't these look similar to the ones Tim has been suggesting since the very first day? Add to these interrupt levels a "COMMAND" topic (where the Open/Save/Close events are delivered) and a "STATE" topic (where the Opened/Saved/Closed events are delivered) and you're (I think) pretty much solving Tim's concerns (Am I right here, Tim?)

Note, though, that Antidote seems to deliver events (interrupt levels) to all bus components. Whether they're interested in listening or not. We may refine this a little bit to avoid bothering components with events they're not intersted in.

Traffic lights for bus lines

And here we come to the tough part. Decide how to coordinate that event traffic. Decide which events go in which bus lines. Define how many topics. Place some traffic lights somewhere.

After all, as Ronan Bradley (CEO, PolarLake) clearly stated, the ESB is just a communication mechanism. The mediation, the orchestration, is the tough part.

So I can think of different mechanisms and I would like your feedback on this.

I. Event aggregators as event sinks

The very first approach is having one or more listeners of the bus holding instances of other components. These aggregators will receive different events from different components in the bus. And will then orchestrate them, making direct method calls on those components. Note that these are listen-only aggregators.

  • One of these aggregators (status bar aggregator) would listen the bus for the "FileSelected" and "FileOpen" events and then invoke the "statusBar.setMessage(...)" on the status bar.

  • Another of these aggregators (editor aggregator, say) would listen the bus for the "FileOpen" event (coming from either the menu bar or the filesystem viewer) and then invoke the "editor.open(...)" method of the editor.

Building such aggregators is simple. All macro-components have a single listener: the event bus. And the event bus, in turn, has one or more listeners: the aggregators.

Furthermore, aggregators can talk themselves through the bus. So they're event sinks, but may produce (simulating) events from the components to fire action in another aggregator. For instance, an aggregator could post a "FileOpen" event in the bus, so the "editor aggregator" workflow above will be executed.

This approach is modular too. You can add different aggregators. Adding new features to the GUI requires new aggregators. All control logic is in the aggregators, that manipulate the data model and deliver pieces to components. Components are just pasive views between the user and the controller.

In this approach macro-components are loosely coupled. You don't mix listeners between components. You don't have the status bar listening the filesystem viewer, nor the editor listening the menu bar. One-to-one listeners are gone. Instead all components have a single listener: the event bus.

With this approach there's no need to deliver command events to components, either, because aggregators invoke methods on them directly. So there's no need to veto events. No command events. No need to worry about locking problems: the order of reactions to events is fully controlled, in Java, in the aggregators.

I think this approach architects all this event handling in three layers. See:

  • A view layer, with macro-components, responsible for visual display of data and primary user event handling.
  • A bus layer, responsible for routing events from components to aggregators. Events may be delivered either synchronously or asynchronously.
  • An aggregator (controller) layer, responsible for handling events from components, coordinating them and manipulating the data model.
Maybe a small diagram clarifies things a little bit?

Type I aggregators

II. Event aggregators as event producers

The second approach I can think of is similar to the previous one. "Type II" aggregators will listen the bus for component events, too. But will \*not\* have any instances pointing to the components. Instead of making direct method calls these aggregators would just send events, command events, to components.

  • The "status bar aggregator" could receive the "FileSelected" and "FileOpen" events from the bus and then send a "setMessage" event through the "statusbar" "command" channel.
  • And another of these aggregators, the "editor aggregator", could receive the "FileOpen" coming from the menu bar of the filesystem viewer and then send an "open" command event through the "editor" "command" channel.

This approach seems to be very powerful (does it not, Tim? ;-)).

Since there's not a direct link between macro-components, these may be replaced (by mock macro-components in order to do some gradual functional tests) or may even be absent (and command events would then be simply ignored).

You could even run the whole aggregators with a bus... without a GUI!. Replace all macro-components with mock objects (responsible for receiving and sending events) and you could exercise the whole controller logic.

You could even substitute the presentation logic and reuse the controller logic. So you could have a view layer with SWT and another view layer with Swing, and swap between them both without touching a single line of the controller logic.

Note also that I say "statusbar" "command" channel and "editor" "command" channel, so I suggest having different "command" channels for different components, and not just a single "command" channel to all components. By doing so I think we get rid of vetoing and the lock problems Tim points out (am I right here)?

So, to summarize, these "Type II" aggregators would just replace direct method calls (and instances) with command events directly delivered to components (through each component's command channel).

These "Type II" aggregators would be similar to state machines. You would need for these something similar to Antidote's "ApplicationContext" to keep track of state. You could even program them with, say, the SMC's FSM language (instead of using BPEL, which is only for orchestrating web services in ESBs).

Or you could use some sort of Workflow engine. After all an aggregator just receives and sends events (and keeps state and access the model for data). So some sort of workflow mechanism may be helpful here?

May be is that the future of GUI development? Using some sort of declarative language to manipulate GUI behaviour, once a good set of macro-components is in place? Having workflow editors to program GUIs? Who knows. Maybe we'll have something similar to NetBeans MIDP Visual Editor for building J2SE GUI Applications.

This is a long one

Sorry for such a long post. It's lots of things to think of!

Now, what do you think? Which one would you prefer? Type I aggregators or Type II aggregators? You may already know my preference: I like simple things! ;-)

I'm wishing to discuss. Come on, participate. I'm working for a draft implementation and I'll let you know whenever is ready.

Happy Swinging,
Antonio

miércoles sep 21, 2005

Let's take the bus. The Swing Event Bus.

So continuing yesterday's entry about SOA for Swing and event buses, I thought it could be a good idea to take the Swing Event Bus first. Just to explore how far we can go with it.

I received some emails (and just one comment, thanks Tim!) on this so I thought it could be a good idea to share my thoughts with you (well, after all that's what a blog is about, right). But, more importantly, I would like you so thare ideas with me. So let's participate, suggest (and criticize, of course).

Our starting point

To clarify let's assume we have an application with just four major macro-components:

  • A Filesystem Viewer (FV). A component that visually shows the contents of the file system. Say with a JTree or a JTreeTable. This component is responsible or detecting selections of files, double clicks and drag-and-drop operations.
  • A Status bar (SB). Responsible for showing status messages.
  • An editor window (ED). Responsible for opening text files.
  • A Menu bar (MB). With the usual actions for opening files, etc. Of course some of the items in the menus are enabled and disabled depending, say, on the type of the file and the status (saved/unsaved) of the editor.
Yesterday I described some of the horrors of the Observer pattern in complex GUIs. This is, how the event-source to event-listener one-to-one relationship is a nightmare for big applications. There's another description of some of the problems at Martin Fowler's site (see "Observer Gotchas"), just if you're interested. (By the way, you may find the event aggregator pattern of interest too).

So, to summarize, we want do build a Swing Event Bus that efficiently delivers events generated by these macro-components. Either synchronously or asynchronously. Our main objective is to make these macro-components as loosely coupled as possible. Ideally each one of these four macro-components will know nothing about the rest, although they will be orchestrated and will jointly cooperate to build the user interface of a simple text editor.

(I would like to add a feature here too: the whole thing should be extremely simple to use).

Design Idea I: Different bus lines?

Now let's see how other people are doing this. Let's see further by standing on the shoulders of giants. Let's learn from what it's already done.

The very first feature that comes to my mind is the need for different bus lines. This is what JMS calls Topics and what Werx calls Channels.

The benefit of this, of course, is that we don't have to deliver the events to all bus listeners. We don't have to stop the bus in all bus stops in the city. We reduce the number of bus stops to those in the bus line. Events are delivered (through a channel/topic) to a subset of listeners. And the traffic is more efficient, and our qualities of service improve.

Design Idea II: Separating concerns

I like separation of concerns. Each macro-component must be responsible for its own GUI. Events internal to the macro-component should be handled internally, using event sources and event listeners as usual.

The macro-components should communicate with the outside world by posting specific events to a topic/channel in the bus. For instance, the FV could generate FileSelectedEvents and FileDoubleClickedEvents to the "FV" topic in the bus. And the editor could post EditorSaveEvent, or whatever other, in the "editor" topic in the bus. Don't you think?

Design Idea III: Mediator Pattern?

As Tim suggested there should be a mediator somewhere to coordinate events and macro-components. I think the Mediator Pattern fits nicely:

The Mediator pattern uses an object to coordinate state changes between other objects. Putting the logic in one object to manage state changes of other objects, instead of distributing the logic over the other objects, results in a more cohesive implementation of the logic and decreased coupling between the other objects
Do you think this is a good idea? I see the controller in the MVC here, right? If so, shall this Mediator have direct references to the macro-components? I mean, there're two ways for the mediator to command something to the macro-components:
  • A) Having references to macro-components. Say the mediator has an instance of the "EditorPanel" and just invokes "Editorpanel.open( aFile )".
  • B) On the other hand this mediator could just send an EditorOpenEvent through the "edit" topic of the bus, so that the editor opens it.
I'm afraid that A) above is asking for trouble. I was wondering if that by using "B)" above things should be easier to test functionally? I mean, by storing (and then repeating in order) events received in the bus we could make functional tests easier to reproduce. Am I right here?

Design Idea III: Inversion of control

I received a pointer to Mike Aizatsky's article about Inversion of Control with listeners. I'm not very good at IoC so I don't know if this applies or not here. Does it? How?

Well, that's all today (I'm too tired). I'd like to hear from you!
Cheers,
Antonio

martes sep 20, 2005

SOA for Swing (event handling scalability)

Why UI event handling may not scale

Event handling using event sources and event listeners doesn't scale. Not at least if you don't take dependencies into account. That's a fact. Let me explain.

Think of a Swing application as composed of major "macro-components". Say you have an editor, a settings dialog, a status bar, a console window, a filesystem tree-view for displaying file info, whatever you may think of.

If your application is small then it's probably ok to keep a one-to-one integration between these macro-components. You make the editor a listener of the settings dialog. You make the status bar a listener of the editor. You make the editor a listener of the filesystem tree-view. Easy. Business as usual.

But if your application starts to grow then you're in trouble with a one-to-one integration. After all if your application has "n" major macro-components then you need "n times n" one-to-one integrations. If "n" is 10 then you need 100 one-to-one integrations. That's nightmare. It's easy to have loops of listeners between major macro-components because it's difficult for you to track dependencies, and you don't know who is sending what when. Order of events starts being problematic. You're in serious trouble.

The SOA equivalence

That's exactly the same situation most of our customers are facing inside datacenters. They're in trouble trying to integrate applications when the number of applications grow. It's difficult for them to extract information from those, it's difficult for them to keep information simple. Their information starts to be duplicated in different applications. They're in trouble too.

That's one of the reasons why we've adquired SeeBeyond. To help customers clarify the situation in the applications in their datacenters (and with the rest of the world too). To integrate their applications easily. To reduce their TCO. To make application development easier by using SOA, by easily orchestrating their services in a coordinated way.

The best way to integrate different applications is, of course, by using an Enterprise Service Bus, a major component of most SOA suites nowadays. By using one of these integration becomes scalable. "n" applications require just "n" connectors to the bus, and not "n times n" as before. Easier. Linear scalability in place. Let's grow.

This ESB is responsible for routing the message between zero, one or more applications. Either synchronously or asynchronously. And one application does not need to know to which other applications is connected. That's the way to grow.

The "Swing Event Bus" (and its events)

And the same solution may apply to your Swing applications as they grow. You need some sort of "Swing Event Bus" to integrate your macro-components. Your macro-components send events to this Swing Event Bus and forget. They don't know who is responsible for handling the event. There's not a one-to-one relationship between event sources and event listeners. These are decoupled. You can now scale linearly, you can now grow your application with another macro-component by attaching it to the event bus.

Of course the events transferred by such a "Swing Event Bus" are not "normal" events. I mean, you don't want to transfer ActionEvents from the "File System Viewer" to the "Editor" and the "Status Bar". "Normal" ActionEvents tell nothing to you. You don't mind what the action command of the event is. You don't even mind what the source of the event is. It may be an internal button of the "File System Viewer", a double click on a file or a popup menu.

Through that "Swing Event Bus" you probably want to deliver custom events. Say a "RequestFileOpenEvent", that contains (for instance) the name of the file. Then the "Editor" and the "Status Bar" will receive that "RequestFileOpenEvent" from the "Swing Event Bus" and react appropriately. The editor will probably try to open the file and the status bar will probably show a "Opening file XXX" message.

You can use both, of course!

Of course the "Swing Event Bus" may be used for intra-macro-component event handling. This is, you can use such a "Swing Event Bus" to communicate in-between the components (buttons, popups, menus, lists, tables) of your macro-component (the "editor", say). But that's probably not a good idea. It violates the KISS principle. There's no great benefit of having a loose-coupling between a button and a menu item inside the editor, right?

After all the "Swing Event Bus" should be used just to attain loose-coupling between major macro-components. Using it inside a macro-component makes no sense at all.

So, where is this Swing Event Bus?

Well, the idea of using event buses for Swing has been around for a long time.

The first that comes to my mind (and probably the older one) is the good, old, easy-to-use, withdrawn, almost-forgotten InfoBus specification (we even had some implementations at java.sun.com).

But there're may others out there. There is David Walend's Somnifugi, a lightweight JMS implementation. And werx, for instance.

And I'm not the first one to talk on this either. Berin Loritsch, David Walend, Ryan's Scraps, Lair Nelson and probably tons of others have talked on this before.

So, why talking on this now?

Well, you know I suffer badly from frameworkfobia, so I try to do things myself as much as I can. That, and because I need working out my annotations in Java 5, is the reason why I'm working on UITopics. (Yeah, still waiting for java.net approval :-().

Next posts

This looks interesting, doesn't it? Now let me ask one question: should events transferred through the Swing event bus contain any logic at all or not? What does the SOA simile suggest?

Food for thought. Cheers,
Antonio

lunes sep 19, 2005

Exception topics and typical exceptions

Exception topics

I'm still waiting for the UITopics stuff to be approved by java.net. I cannot upload .jar files to my blog now (some sort of weird filtering or something), so there's nothing I can do but wait :-(

I'm still shifting paradigm between the Observer pattern (used by Swing for event listeners) and the publish-subscribe paradigm that UITopics promotes. I'm still finding new idioms and new features.

Take for instance exception handling in GUIs. Imagine I have a Topic called "application/errors". Now, whenever I have an exception, I post an ExceptionEvent to that topic. Like this:


...
  TopicManager tm = getTopicManagerFromSomewhere();
  try
  {
    doWhatever();
  }
  catch( Exception e )
  {
    tm.postEvent( "application/errors", new ExceptionEvent(e) );
  }
...
where an ExceptionEvent is a custom event...

public class ExceptionEvent extends java.util.EventObject
{
  public ExceptionEvent( Exception source )
  {
    super( source );
  }
  public Exception getException()
  {
    return (Exception) source;
  }
}
This is, I just send the event to the "application/errors" for whoever listeners may be there.

One topic listener just (asynchronously? yes, why not...) logs the stack trace...


  @TopicListener( topicName="application/errors", isAsynchronous=true )
  public void logException( ExceptionEvent ee )
  {
    System.out.println( ee.getException().printStackTrace() );
  }
While another, in the Swing thread, shows a message dialog:

  @TopicListener( topicName="application/errors" )
  public void handleExceptionWithPopup( ExceptionEvent ee )
  {
    JOptionPane.showMessageDialog( 
      ... ee.getException().getMessage() ... 
    );
  }
This is somewhat powerful. I can attach (or deattach) any of the listeners. I may have a listener for debugging purposes that prints out all exceptions. I may even have a listener that logs all events into a topic and replays them later on (to emulate user input).

Yes, definitely shifting paradigms is interesting.

Typical exceptions

On other news, I received my september copy of "Communications of the ACM" today. I just opened it and I could read:

Can you spot the security flaw?

  Try {
    Byte [] text = AccessPlaintextData();
    Byte [] password = GetPassword();
    ...
    EncryptData( text, password );
    ...
  } Catch() {
    // exception code
  }
  
"This pseudo-code reflects a somewhat common flaw ... in .. M$$soft Internet Information Server 4.0 ..."
Now, remember that article at artima about checked exceptions in C#? In the article Anders Hejlsberg said "I see two big issues with checked exceptions: scalability and versionability."

Now, my conclussion after reading that article at Artima and the ad at magazine is: in C# there're no checked exceptions because of lack of scalability and versionability at the cost of lack of security (!?).

Well, it seems that after all James Gosling was right when saying:

- What does "solid" mean?
- James Gosling: Solid means you can run the software day in and day out. When the usual crazy things happen, the software survives.

Now, I'm glad I have checked exceptions in Java!
Happy Swinging,
Antonio

About

swinger

Search

Archives
« abril 2014
lunmarmiéjueviesábdom
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Hoy