3

I'd like to have a GWT app with a UI that is configuration-driven, meaning that if I make certain database changes, or deploy a different XML descriptor (outside the WAR), then I can change the look, feel and behavior of the UI without deploying any code changes. My reasons for wanting this lay outside the context of this question and I would need to provide way-too-big of an irrelevant backstory to justify placing it all in this question.

For instance, say with one particular configuration, the UI (a place in GWT verbiage, or page/screen) might just consist of a simple button in the center of the screen. Then, I make some database changes, and now, the same place renders with 4 buttons in each corner of the screen, and a "Hello, GWT" label in the center. Same code, but different DB values (or XML) cause the UI to look/feel/behave differently.

I'm trying to figure out how to design such a system, but am struggling and not sure if it's even possible. If it is possible, I'd appreciate a good explanation on how it might work, and maybe even some pseudo-code to get the creative juices flowing.

If it's not possible, then I'd like a concrete (definitive) answer as to why. As I've found on StackOverflow so many times now, when someone says "this is impossible!" it's usually just an advanced topic that is beyond their level of understanding :-), and what I'm asking isn't impossible, it's just hard! Thanks in advance!

IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756

1 Answers1

2

Yes, this is definetely possible. I've went once through that.

But it's not a standard way of doing, so don't expect to find much in internet. You must invent the solution yourself.

Simply, you must create a channel/service/JSON service from which the GWT application will read your configuration, and build the UI according to it. You can invent your own description language, or use some existing format, for example XUL, to describe the UI. It's however a hard way, but giving a lot of satisfaction once you accomplish it.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
  • Thanks @lechlukasz (+1) - I appreciate the encouragement, but have a few followups: (1) can you elaborate on what you mean by "channel"? I was thinking about perhaps storing UI XML (I like your suggestion for XUL!) configuration in a database and just use best practices with RequestFactory for obtaining the stored XML. Is this what you meant? And **most importantly**, (2) I know that GWT does not like relection very much and that there are certain things with Java reflection things it can't do (because the JS cross-compiler can't honor it)... – IAmYourFaja May 10 '13 at 11:42
  • ...So I'm wondering *how* this is possible: how, on the server-side, do I take XML/XUL, and use it to dynamically create new UI widgets and send back to the client-side; but in such a way that GWT (and the cross-compiled JavaScript) can support? Do you have any code samples from the project you were able to do this for? I guess I'm having a tough time "seeing the forest through the trees" here. Thanks again! – IAmYourFaja May 10 '13 at 11:44
  • 1
    Well, you'd parse XUL on server side, but the widget creation you must do on client side. An no, I don't have any code samples and I know nothing about any open-source implementation of that kind, so you have to deal with writing really a lot of cliend-side code. Lack of support for reflection in GWT means, that you'll have to handle tags by if/switch statements, and yes, that makes that code even bigger. – Danubian Sailor May 10 '13 at 12:09
  • Thanks again @lechlukasz (I wish I could upvote this more). Before you updated your answer, I was thinking about the following design: (1) use a XUL toolkit to design my different UIs and generate XUL. Then, save the new XUL to my database. (3) On the server-side, I have a `ViewService` that each GWT Presenter (I'm using MVP) can use to fetch its respective View from. So a `FizzPresenter` would get back a `FizzView` from a `ViewService#fetchView(FizzPresenter.class)` call. Under the hood, (4) the `ViewService` uses a `XULBuilder` class to fetch the XUL from the database and turn it... – IAmYourFaja May 10 '13 at 12:11
  • ...into UI components. **Is this a feasible approach? If not, why?** If possible I'd like to do all the dynamic view-rendering on the server-side... – IAmYourFaja May 10 '13 at 12:12
  • Wel, no, you can't render UI components on server side, because there's no HTML sent to be placed into page, like in JSF. GWT constructs elements using DOM operations, so you must send the intermediate structure which will be processed on the client side. That's the only way I know of. – Danubian Sailor May 10 '13 at 12:20
  • Okay, I think we're getting somewhere: can you give me an example of an "*intermediate structure*"? I think once I understand what that means I should be able to solve my problem. Thanks again for all the great help so far @lechlukasz! – IAmYourFaja May 10 '13 at 12:39
  • Something like mapping hierarchy for view classes, abstract class ComponentConf, ContainerConf having collection of ComponentCof, implementations such as MenuConf, TextInputConf etc... – Danubian Sailor May 10 '13 at 12:43
  • Ahhhh, I *think* I get it: so these `XConf` (`MenuConf`, `ButtonConf`, etc.) classes would be simple Java beans/POJOs sent back from the server to the client, and then on the client-side, I would need to translate them into actual UI controls, yes? – IAmYourFaja May 10 '13 at 12:47
  • Yes, exactly, so you'll have quite a lot of classes and quite a lof ifs to handle them. – Danubian Sailor May 10 '13 at 12:49
  • There isn't often a specific structure that you'll want to follow either - as a developer who wants to generalize, you probably want to write this framework on top of gwt once, and then develop all your apps in that, but that is going to have several side effects. First, you'll end up building a conf object for every possible situation, and just to tell the real widget what to do, and second, you'll be limiting what the compiler can do, so you'll have very large compiled sizes. Try to build these conf objects so that it solves only the problem you have now, and can be extended later. – Colin Alworth May 11 '13 at 00:57