ObjectWeb Consortium
Search ObjectWeb Mail Archive: 

Advanced Search - Powered by Google

Mail Archive Home | xmlc List | May 2000 Index

<--  Date Index  --> <--  Thread Index  -->

Re: Rocks: 'Rocks Presentation Framework' document

Peter: thank you for your excellent contribution: I'm going to read it a few
times over the weekend to make sure I get all the points you are making, and
I'll be discussing it with Mike Ward, hopefully early next week.


----- Original Message -----
From: Peter Antman <pra@xxxxxxx>
To: <rocks-group@xxxxxxxxxxx>
Sent: Thursday, May 25, 2000 6:49 AM
Subject: Re: Rocks: 'Rocks Presentation Framework' document

> Hi,
> I thought I should give some feedback on the interesting document
> "Rocks Presentation Framework". Just my five cents though (and excuse
> me for my somewhat broken English, its not my mothertoungh).
> I have been looking for a good MVC based framework for
> webdevelopment the last one and a half year, I have even build the
> basis of two ones my self and tested some others, but without
> satisfying results.
> Last Christmas I discovered XMLC and Enhydra, and I
> think it is the best approach I have seen yet. It would be really nice if
> XMLC could get a somewhat more high level API to work with the DOM. A
> simple approach, which would do a lot of good, could be to just build a
> widget set, where each widget was configurable with a pointer to the
> DOM element to work on, and with a data model to get data from, and
> perhaps also one ore more events to react on.
> But now I have gotten carried away. Perhaps we should start with
> trying to cope with the semantics of the Web and MVC. I think you have
> done a good job of explaining MVC, and the likeness and differences
> between a standard GUI application and a web application. But I also
> think there are a couple of problems and unresolved tension still there.
> Lets reuse GUI terminology even more than you do. I think it might be
> possible to view the incoming request from a client as the
> "eventloop". As long as the eventoop is active - i.e the client keeps
> browsing - that clients instantiation of the application is also
> alive. The response could then be viewed as the "repainting".
> We may further say that the eventloop carries with it events that the
> application must service. For simplicity's sake we can say that the URL
> is the main eventloop, for example www.foo.com/bar.po, and that the
> individual arguments are the events, eg ?foo=bar.
> Given this, and your explanation of MVCm we can come up with some
> problems to solve (here given in an unstructured way).
> 1. Eventstatus.
> Compared to a stand-alone GUI client, there are actually two types of
> events coming in in a web request/event loop:
>        a) Events carrying state
>        b) Events marking something new has happened
> Say we have an application with three pop-ups (selects) A, B, C,
> interconnected with each other in such a way that when an entry in A
> is selected the content listed in B will change, and when an entry in
> B is selected the content listed in C will change.
> When the application first is triggered by an URL with no arguments
> the default page is painted. Next time the client has selected an item
> in A. An event ?A=1 has perhaps come in. This event in its turn should
> lied to two things. The model for A should update it self to set the
> selected item as the currently selected, which in its turn should lied
> to the widget A repainting itself. It should also lied to the model
> for B to update itself with some new content and finally the widget B
> to repaint itself.
> In the next eventloop the user has selected an item in B. However this
> will lead to two events: ?A=1&B=2
> In a real client MVC GUI this would only lead to the following. The
> model for B should mark the item as the currently selected, and the
> model for C should update its content, and C would repaint
> itself (and probably B). But how should we go about in the web case.
> For at least A, but in some way also for B, these events are not real
> events: they only carry state information, saying to the model and
> the  widget to remain the same.
> This may seem trivial for every one knowing how HTTP works, but I
> still thinks it is important to draw attention to it, since it breaks
> some of the inherent good things with the MVC pattern. Without a
> solution to the different types of events coming in, we will get an
> application that will bootstrap itself (ie building all the connection
> and all state) each time a client request comes in, only with
> different initial state (i.e the arguments need not be viewed as events
> at all, but only as holders of state).
> More about this problem further down.
> 2. Id of events must be known at several places.
> If we skip the Model for a moment and look at the View as something
> that generates HTML, and the Controller as something that receives
> requests, who knows which View object to use, and emit a response, we
> spot a possible encapsulation problem. As we all knows the name of the
> events coming in via the parameters steams from name attributes in
> form tags (or from an URL constructed in some other way).
> Say we have a pop-up view widget representing a select HTML tag. The
> name attribute on that widget would also be the name of the event
> coming in. This might have been written as pure HTML, and perhaps
> compiled to a DOM tree by XMLC. Without a solution that in some way
> centralizes, or monopolizes, the way we give these widgets there names,
> the result will be that both the View/Widget and the Controller must
> know the identity of the event. The View must know it because it must
> be able to render it into the browser, and the controller must know it
> to be able to react to it, and connect it to the correct widget.
> Both problems above points in the direction that some cind of well
> designed event handling mechanism is needed in an MVC framework for
> the web.
> 3. What are the models?
> In the paper you do a good job of explaining what responsibilities the
> View and the Controller has, but states that the "model may include
> anything except presentation layer logic". This is offcource fine in
> general terms, but I do think that it at the same time is really good
> to have a strict set of generic Model API:s.
> What do I mean by that? If we look at how the Swing is done, each
> widget also have a model connected to it. These models follows well
> defined API:s for each type of widget; JButton having a ButtonModel,
> JComboBox a ComboBoxModel and JTable a
> TableModel/TableCollumnModel. By doing it this way it is easy to
> write your own models for the widgets, and more important, it makes it
> possible to write adapters for different kinds of data sources. You
> may, for example, connect a ComboBoxModel to a JDBC connection or an
> EJB bean. This becomes useful when you have data objects
> following a generic interface, because it is the possible to write
> configurable adapters.
> Here is an example, partly based on the kind of proxy data object that are
> generated by the EJB Generator toolkit Percolator
> (This code may even be invalid java code, its just a pseudo example)
>       //...
>       // Create a select model wich adapts a data layer proxy object,
> // The two last arguments specify wich attributes to use from a
> // UserProxy to set the option name and label
> ProxySelectAdapter model = new ProxySelectAdapter(new UserProxyManager(),
>    UserProxy.K_NAME_USER_ID,
>    UserProxy.K_NAME_LOGIN_NAME
>    );
> // Create a standard widget for popups (selects). This beast should
> // Know how to both just stand in for a DOM element, but it should also
> // know how to do intelligent cloning of nodes to keep style attributes
> // given from an HTML-file, and compiled with XMLC
> PopoupWidget widget = new PopupWidget( model );
> // application here stands for a fictous central controller object, in
> // wich we can register a widget to be used to put into an XMLC DOM
> // tree automaticly, and to register interests in perticular events
> // Connect widget with ID in XMLC tree, the event name is automaticly
> // set by application
> application.addWidget( "userIdSelect", widget );
> // Register interest in a particular evevent.
> application.registerEventCallback("domainIdSelect",
>   new WebEventListener() {
>   public void handleEvent(WebEvent ev) {
>       Integer di = ev.getInteger(1);
>       model.updateByMember(K_IDX_USER_ID, di);
>   }
>       }
>   );
> application.registerEventCallback("userIdSelect",
>   new WebEventListener() {
>   public void handleEvent(WebEvent ev) {
>       Integer di = ev.getInteger(1);
>       model.setSelectedId(K_IDX_USER_ID, di);
>   }
>         //...
> 4. Widgets, layout and renderers in HTML
> One of the more problematic features of HTML when it comes to writing
> a generic widget kit is that tags are used both as classic widgets and
> to do layout. Say that you have a fancy TableWidget with an
> accompanying TableModel. Your web-designers designs a nice hit list of
> some kind, where the data from your TableModel should be used. Chances
> are good that the TableWidget will be completely unusable, since the page
> will be chock full of tables to define the layout; and the logical
> table will probably be nearly impossible to identify.
> Another problem in the same vain is the need to often do condition
> based rendering. Say you have data, which sometimes contains an URL and
> sometimes contains nothing. When there is an URL, some text should be
> surrounded by <a href="URL">TEXT</a>, when the URL is not there, the
> text must be plain. Say that a particular cell
> in a TableWidget must have this logic. How do one solve that? One
> possible way might be to define special renderers which may be attached
> to a specific cell, something in the line of the decorator pattern.
> An abstracted View framework would offcource be usable if it
> in some vain followed the path of Swing and made it possible to work
> with different windowing environments (plaff), in the web world
> meaning it could represent the widgets in different kinds of
> presentations markup (HTML 3.2, HTML 4.0, pure text, WML, some XML dtd
> or Avantgo compatible HMLT, just to mention a few). But to get this to
> work you will basicly have to build the whole application by
> hand coding it like you normally do when building a GUI-application.
> A possible compromise solution for XMLC might be the possibility to
> specify a factory to get the widgets through. Then it might be possible
> to set up different representations of an application just by starting
> it with some kind of environment variable.
> Say we have three representation of a page, App.html, App.wml and
> AppGo.html. And we had a way of telling the dynamic page loader in
> Enhydra to chose a particular class depending on some variable, and
> that the pages followed a particular interface, then we might write
> code like this.
>      App app = (App)comms.xmlcFactory.create(App.class);
>      ProxySelectAdapter model = new ProxySelectAdapter(new
>    UserProxy.K_NAME_USER_ID,
>    UserProxy.K_NAME_LOGIN_NAME
>    );
>      PopoupWidget widget = WidgetFactory.getPopup( "selectSome", model );
>      String id = comms.request.getParameterValues("selectSome")[0];
>      int selId = Integer.valueOf( id ).intValue();
>      model.updateByMember(K_IDX_USER_ID, selId);
>      widget.use( app.getElementSelectSome() );
>      //...
>      comms.response.writeHTML(selectType.toDocument());
> 5. How to connect everything
> As I have already suggested there are some inherent problems in an MVC
> approach to web development. Lets take a look at two possible scenarios
> (I have implemented both of them in tests and custom made systems).
> 5a. Emulate the client at the server
> One way to go is to emulate a fat client environment at the
> server. You could do it by associating an application with a client
> session, set up all the connections (widget/controller/model and
> listeners) when a client first connect and then sort of save it in the
> session object. The connection between the application and the
> incoming request could then be handled by a WebEventMulticatser, that
> knows how to find the application object, that keeps control of the
> events different parts of the application is interested in, and
> keeps a record of the last events so that it only sends
> events to the application when there are real events and not only
> status events.
> I have tested this approach once, with WebMacro and custom build model
> adaptors for CocoBase data objects. The application get really fast,
> since it does not need to set up all relations and fetch all the data
> all the time. On the other hand: it eats a lot of memory.
> If I am not wrongly informed it is also the way WebObjects work (with
> some intelligent data object caching and sharing under the hood).
> 5b. Build it from scratch every time
> The approach above might be a workable model when there aren't that
> many clients connecting concurrently, but for highly loaded servers
> the resources used will probably quickly get too high.
> The other approach is to use the MVC pattern more as a way to write
> cleanly designed and robust code, but to let the application bootstrap
> itself from scratch each time, initializing itself with the events
> coming in (i.e by viewing all incoming events as status holders,
> more than actual events.)
> I have done this too, in a small MVC perl framework (running the
> Swedish site: http://www.jobb.dn.se/).
> Here is the stub for a meaningless application with a select:
> # Get the Apache request object
> my $r = Request->new( Apache->request );
> # Tell apache (and client) that we will generate html
> $r->content_type('text/html');
> $r->send_http_header();
> # Construct Model(Wraper) for main_search
> my $main_model = MainModel->new( $r );
> # Construct Top level view
> my $top_view = TopView->new();
> # Construct View for main_search
> my $main_view = MainView->new();
> # ad its model
>         $main_view->set_model( $main_model );
> # Add the panel view to top level view
> $top_view->add( $main_search_view );
> # Return HTML, via a recursive parse of all
> print $top_view->parse();
> Here the MainModel is just a container for sub models to make the top
> script a little bit easier to read. Part of the code in the MainModel
> could look like:
>       my $BRANCH_EVENT = 'selectBranch';
>       my $ORT_EVENT = 'selectOrt';
>       #...
>       my $branch_id = $r->param($BRANCH_EVENT);
>       my $ort_id = $r->param($ORT_EVENT);
>        # create Ort Db object
>        my $ort_db = DnJobb::Db::OrtCount->new();
>        if ( defined($branch_id) and $branch_id ne '-1' ) {
> $ort_db->branchid( $branch_id );
>        }
>        my $ort_model = new DbAdaptor::SelectAdaptor->new(
>                                                        $ort_db,
>                                                        'ortid',
>                                                        'ortlabel',
>                                                        $ORT_EVENT
>                                                       );
>       $ort_model->update();
>       # Ad default selection
>       my $default_option = Model::OptionModel->new("Alla", -1);
>       $ort_model->ad_option( $default_option );
>       # Is there a selection in the ort popup?
>       if ( defined($ort_id) and $ort_id ne '-1' ) {
>         $ort_model->set_selected_value( $ort_id );
>       } else {
>       # Select default
>         $ort_model->set_selected_value(-1);
>       }
> And in MainView it could look like this:
>       # Get the model
>       my $ort_model = $self->{'MODEL'}->get_ort_model();
>       # Create ort popup
>       my $select_ort = vHtml::Select->new();
>       $select_ort->set_model( $ort_model );
>       # Set the jscriptevents
>       $select_ort->set_event('onChange="reload()"')
>       return $select_ort->parse();
> This way of doing it will not eat that much memory, but will be a lot
> slower since the logical application, all models, data objects and so
> on are created a new at each request.
> With some form of caching data layer behind, the penalty might not be
> all that high. It would be nice anyway to find a working compromise
> between these two ways of doing it.
> 5c. a compromise
> An interesting alternative would be to ponder the fact that the state
> of most dynamic HTML pages is not endless. If it was possible in some
> way to keep a pool with some kind of representation of all possible
> states for a specific page that has been loaded, we could reuse these
> states instead of creating a new instance of the application each time
> a request comes in.
> I must say that I do not know at all currently how this could be done,
> but I think that some mechanism that pools widgets and perhaps the
> models connected to them, and that the controller part have to use the
> incoming event to chose from that pool, is necessary to both get
> scalability and fastness in a generic MVC framework for the web.
> I hope I have not tired you down to much by all this text; and that it
> wasn't to much of topic.
> Greetings Peter
> --
> ------------------------------------------------------------
> Peter Antman Technology in Media, Box 34105 100 26 Stockholm
> Systems Architect WWW: http://www.tim.se
> Email: pra@xxxxxxxxxxxx WWW: http://www.backsource.org
> Phone: +46-(0)8-506 381 11 Mobile: 070-675 3942
> ------------------------------------------------------------
> --------------------------------------------------------------------------
> To unsubscribe from this mailing list, send email to majordomo@xxxxxxxxxxx
> with the text "unsubscribe rocks-group" in the body of the email.
> If you have other questions regarding this mailing list, send email to
> the list admin at owner-rocks-group@xxxxxxxxxxxx

To unsubscribe from this mailing list, send email to majordomo@xxxxxxxxxxx
with the text "unsubscribe rocks-group" in the body of the email.
If you have other questions regarding this mailing list, send email to
the list admin at owner-rocks-group@xxxxxxxxxxxx

<--  Date Index  --> <--  Thread Index  -->

Reply via email to:

Powered by MHonArc.

Copyright © 1999-2005, ObjectWeb Consortium | contact | webmaster.