General design question

Hello,

I am a new user of Vaadin and want to ask for your opinion on the following solution pattern I am considering using:

The problem:
I want to create forms with localized field captions. The fields will be created by my own FormFieldFactory implementations that set the caption of each field by retrieving localized captions from provided ResourceBundles. However, as my CustomComponents containing the forms are constructed before they are added to the component hierarchy, the application and its current locale are not available during construction. Hence, I cannot simple assemble the form’s components in the constructor as I would normally do (which seems to be the standard Vaadin way).

My suggested solution:
To create an abstract base class LocalizableCustomComponent that overrides attach() and calls the abstract method createLayout(ResourceBundle) that must be implemented by derived classes. This pushes the actual assembly of my forms until the forms have been added to the component hierarchy and the locale is available for supporting the retrieval of the appropriate ResourceBundle (in LocalizableCustomComponent.attach()).

My questions:

  1. Does this solution come with some kind of performance penalty, since the class that contains the form (initially empty) is first added to its parent and only then populated with its contained field components?
  2. Are there any other drawbacks that you see with this solution pattern?
  3. Is there a better way of accomplishing localization of field captions than what I suggest above?

Your insights and comments would be much welcome!
Thanks,
Thomas

I’m not an expert, but how is it that you don’t know the locale before you are constructing a Form for a user?

In our system, we have a “default locale” that is set for the application. Then, each user can have overrides, but the user authenticates and sets this value before we’re building Forms for them.

How is it you are building any UI component before you know who the user is and what their locale is? Please explain how it is that you are building these before you know the locale? It is quite normal to use localized resource bundles for labels and messages to the user, but I’ve not heard that you’d need to construct any of these before you know who the user is – or you use app default bundles… Or if the user can switch locales on the fly, then you will need to recreate the UI components after they make the change.

If you want to, you can take a look at the
AppFoundation
add-on, which provides an
i18n module
. If you open up the latter link, browse down to the section where FieldTranslations are described. FieldTranslations is a generic way to localize field captions in a form according to the pojo fields.

Another option is for you to use the
ThreadLocal pattern
which allows you to get the current application instance in a static way. This means that you can fetch the local from the application even though your component is not attached to the component hierarchy.

I think that solution is good and I don’t think that it has significant performance penalty. One drawback that comes to my mind is the case where the creator of such a composite component wants to access its subcomponents right after the creation, but I suppose that’s very rare.

The trivial solution is to just pass the application object to the constructors of CustomComponents, so they don’t have to wait until they are attached. See for example the
FillEditor
. Passing the app object around and storing it is quite annoying, but a postponed initialization mechanism adds some extra obscurity to the application, which is also not good. A small advantage is that a “[tt]
app
[/tt]” variable is shorter than “[tt]
getApplication()
[/tt]”.

A bit exotic solution would be to give a temporary caption text that is replaced later by iterating over the UI after all the components are attached (at the end of the init() method in the application object). The temporary caption would hold the resource key. Well, the key could also be stored with setData() or something. This solution feels a bit uncertain though.

This is an interesting topic and I’d also like to hear what other solutions people have found.

The application locale is accessed by a call to the Vaadin standard method Application.getLocale (see chapter 5.3.5. in Book of Vaadin). In order to call this method I must first get the application object, which I get by calling getApplication from my component class (in my case I derive from Vaadin’s CustomComponent to embed the form and everything that goes with it).

The crux is that getApplication returns null until the component has been attached to the component hierarchy. This attachment does not occur until after the constructor has returned, which means I cannot complete the assembly of the localized form in the constructor. Instead I wait for the framework’s callback to attach(), which signals that getApplication will now return a valid object and not null. However, this seems to go against the normal Vaadin way of doing things, where components are always assembled in the constructor of the containing object. Hence my question.

Very interesting. I have gone through the AppFoundation docs and think you’ve got the most interesting areas covered. Looks good! Since I am on a learning mission, I will probably roll my own implementations for now (I learn best by doing my own mistakes :-)) but I will certainly use AppFoundation as a great source of inspiration. Actually, its implementation of FormFieldFactory is not too dissimilar from what I had in mind.

Using a ThreadLocal is a good idea, I guess it sort of ressembles Marko’s idea of passing around the application reference explicitly, except that the reference doesn’t actually have to be passed around… That raises the question why getApplication cannot provide such an implementation by default - after all, with a lot of action happening in the constructor, it would be nice to always be able to call getApplication without hassles.

Good points. I have confirmed that my solution works but I would prefer to stay on the beaten track and thus assemble my components in the constructor the “standard way”. The ThreadLocal concept suggested by Kim above is a nice way of creating a “non-static static” without having to pass the reference around explicitly and I think I will go for that solution. But I agree that “app” is shorter than “getApplication()” :-). As I suggested in my reply to Kim, I think a ThreadLocal-based implementation of getApplication() could be a nice feature to have by default in Vaadin. As my use case proves, sometimes you really want to be able to access the application object already during component construction.

BTW, while I am “on the line”, let me compliment you guys at IT Mill for a wonderful framework. I have gone through most of the well-known web frameworks out there and nohting has quite struck me as what I want (JSP and its descendants are plain awful, I don’t like JavaScript and I hate XML). But Vaadin is just - lovely! From what I have been able to see sofar: good design, excellent documentation and fantastic support. Just being able to get forum replies on Midsummer Day… (I thought I was the only guy in the Nordic working now :-))

We pass in our application object via constructors, which is why we’d not seen the issue you were having. One advantage is that your Application subclass may very well have lots of useful add-ons that are not available in Application itself, which is the case for us, so the benefit of calling a getApplication() and then casting it to our subclass to get at the goodies just seemed as much if not more work than just passing it into our components’ constructor.

I agree with you that the Vaadin folks have built a very nice framework. :slight_smile:

Point taken, there are many different ways to cut a cake :grin:. Thanks everybody for valuable comments, they helped me to move one step up the Vaadin ladder. I’ll be back with more questions later, no doubt… Cheerio! /T.