$URL: svn+ssh://christianc@svn.forge.objectweb.org/svnroot/barracudamvc/Barracuda2/trunk/WEB-INF/src_docs/architecture/comp/overview.html $ - $Revision: 125 $

Component Model Requirements

This is something of a legacy document - it describes the initial set of requirements for the Barracuda Component Model model layer, and may be helpful in understanding the underlying philosophy which drove subsequent design/implementation decisions.  

  1. Overview
  2. Key Differences
  3. Presuppositions
  4. High Level Goals
  5. Component Requirements

Overview

Developers who come from a client-server background are probably familiar with component models used in those environments (Swing, AWT, MFC, etc). In such a context, a component model provides a convenient series of "widgets" which make it easy to get data onto the screen--put the data into the component, and it will take care of the rendering. In addition, many client-server component models address other issues as well:

It is worth noting that the client-server view of components presented here tends to be fairly low-level, where specific components are often concretely defined by a handful of classes and interfaces.

We should point out that there are other, higher-level definitions, which tend to view components from a much looser perspective. When approached from this angle, a "component" can really be any block of semi-reusable code--people often speak of a package, framework, or even an entire application as a "business component", even though it may be composed of hundreds of classes and may not actually implement any kind of "component" interface. (As an example, there are no standards defining a "Logon Component" or "User Component"...these are high level terms, and as such the component terminology is appropriate in a much looser sense than we find at the "UI Widget" level).

Interestingly, most of the component work being done in the web-app paradigm today is taking place at this higher level; J2EE for instance, touts itself as an "enterprise component model"--this is certainly true, but in a broad, high-level sense. There are very few approaches to building web-apps that are seeking to create a "component model" in the more traditional, "widget" level sense of the word.

With Barracuda, our goal is too create a set of low-level widgets whose primary purpose is to facilitate the rendering of client-views from within the presentation layer of a web app. As such, the Barracuda component model will follow the lead of traditional client-server component models--especially that of Swing--to create strongly typed classes that implement a series of well-defined interfaces specific to this problem domain.

Consequently, when you hear us talk about the "Barracuda Component Model" it is imperative to remember our definition--we are speaking of a low-level, well specified, UI widget framework that is tailored for the intricacies of the web-app paradigm.

Key Differences

While it is true that most web-app development work tends to view components in a high level (more abstract) sense, there have been some interesting experiments in trying to apply existing client-server models directly to the web-app approach. Hammock, WingS, and several others provide notable examples of these attempts. The results, however, have been fairly disappointing.

While some will conclude from this the impossibility of making "widget" components work in a web-app environment, we believe the problems come from failing to recognize--and account for--the differences between the client-server and web-app paradigms. In fact, there are a number of important differences which must be considered when designing a component model.

Presuppositions

Given the difference in rendering roles identified above (data vs. layout), we can identify several core presuppositions:

  1. Since application layout and design is delegated to client side markup technologies (HTML, WML, XML, etc), the primary responsibility for components will be to render data into the markup structure. The server puts data into the markup templates; the client container renders the resulting templates into the actual client interface.

  2. The best way for the component model to interact with the client templates is through the DOM interfaces, since these provide a standard object model that can be used to process a wide variety of specific file formats. In the future we may also want to support components' rendering into flat file structures as well.

  3. XMLC provides an excellent mechanism for compiling client side templates into DOM structures which may be manipulated through the DOM interfaces. Such DOM "precompiling" yields significant performance benefits. Consequently, Barracuda will use XMLC as the default template-to-DOM conversion mechanism.

  4. The general rendering cycle will probably look something like this:

    • load a DOM template
    • assemble a hierarchy of Barracuda components, each of which may be bound to a specific node in the DOM template
    • render the Barracuda component hierarchy (thereby inserting data into the DOM)
    • render the DOM template (thereby sending the results back to the client)

    The actual implementation specifics of such a rendering cycle could vary dramatically (ie. a programmer could invoke each of the steps manually (ie. push-mvc), or a "template engine" might perform all of the steps in the proper order, allowing the developer to simply respond with components as individual data points are encountered in the template (ie. pull-mvc), or there might be some combination of the two).

  5. We think Swing is a great client-server component framework, and as such expect our web-app component model to share a great deal of commonality where appropriate, especially in defining strongly typed Model interfaces (which are themselves persistence layer neutral).

  6. Because of the data vs. layout distinction inherent in the web-app paradigm, however, we expect components will be tailored more towards data rather than representation. As an example, in Swing we encounter a number of Button components (JButton, JToggleButton, JCheckBox, JRadioButton, etc). The distinction between these components lies primarily in how they look and feel to the user. In a web-app paradigm (where the user-interface is markedly simpler), we might easily be able to handle all these scenarios with a simple "Action" component that allows the developer to set text and specify an action to be fired. This means we will probably have a smaller number of UI widgets than we might find in a client-server component model like Swing.

High Level Goals

There are several high level goals.

  1. Create a set of basic components that can be used to manipulate/populate the dynamic portions of a template "View".
  2. Look to the Swing model for guidance, while recognizing the unique aspects of the web-app paradigm
  3. Ensure that the templates remain 100% valid markup and free from server-side presentation logic.
  4. Support both "push" and "pull" mvc approaches.
  5. Make it possible for developers to avoid the low-level programming details inherent with the DOM interfaces.
  6. Provide strongly typed "Model" interfaces where appropriate (ie. for more complex data structures)
  7. Allow components to support the notion of listeners, which are capable of handling "events" that are generated on the client.
  8. Support the notion of component reusability (where a "component" could be a high level assemblage of Barracuda components, as well as static resources like templates, images, etc). Allow for such reusable components to be packaged into standalone JAR files.
  9. Support the notion of custom renderers to handle different types of clients. For example, a given component hierarchy should be able to render either HTML, WML, or XML, depending on the client (and its capabilities). Such renderers should be able to be set dynamically, without requiring compilation changes to the base components.
  10. Implement the components in such a way as to facilitate integration with IDEs (again, similar to Swing).

Component Requirements

Given our goals and presuppositions, we can identify a number of basic requirements.

In General...

  1. Components - should support the notion of ...
    1. Name - should be able to name components
    2. Hierarchy -
      1. All components should have a parent, except for the root component (whose parent will be null)
      2. A component should be able to contain any number of other components (as in Swing)
      3. Rendering a component consists of rendering that component plus all of its child components
    3. Views -
      1. A component may have 1 or more views
      2. When the component renders, it is responsible for representing its data in each view towhich it is bound
    4. Validity -
      1. "Invalidating" a component causes the component and all its parents to be marked invalid (just like in AWT)
      2. "Validating" a component cause the component and all its children to be marked invalid (just like in AWT)
      3. A component is considered invalid until it has been rendered
      4. A validated component does not need to be re-rendered
    5. Visibility -
      1. A component may be visible or invisible
      2. If a component is invisible, the views to which the component is bound should not be displayed when the DOM is rendered
      3. When setting a component's visibility, it should be configurable as to whether that setting applies to just that component or to all its child components as well
    6. Enabled/Disabled -
      1. A component may be enabled or disabled
      2. If a component is disabled, it may (or may not!) affect how the views are rendered (depending on the specific nodes to which each view is bound)
      3. When enabling or disabling a component, it should be configurable as to whether that setting applies to just that component or to all its child components as well
    7. Data - (opt)
      1. Most components will be associated with some kind of data
      2. Simple data can be stored directly in the component
      3. More complex data will often be stored in a component's Model
    8. Rendering -
      1. Render all data associated with the component into each of the component views
        1. This rendering should occur in light of client/request specifics identified in the ViewContext
        2. Components should take advantage of custom renderers to handle different client types
      2. Render all child components as well
    9. State -
      1. All components should be capable of carrying additional "state" information (key-value pairs) which is distinct from a components' data.
      2. This allows developers (or tools!) to associate information with a particular component without actually modifying the component's data
    10. Single-threaded -
      1. components should generally be considered single threaded; they should not be expected to render in a threadsafe fashion (ie. to support multiple render requests simultaneously)
    11. Q's - Open issues...
      1. what about making components Cloneable? Serializable?
      2. what about the supports() method?
  2. Models -
    1. A model's primary responsibility is to act as a data store for the component; a developer puts data into the model, and the component takes data out when it is time to render
    2. When a model is updated it should notify the component (which usually causes it to be invalidated)
    3. A model should be able to return several different kinds of data (just like in Swing):
      1. String data
      2. DOM Nodes (markup)
      3. Other components
    4. Every model should contain a reference to the current view context (except a ListSelectionModel)
    5. A model will generally only service one component at a time (not asynchronous, so even if you have multiple components using the same model, those components could not both be rendering at the same time).
  3. Views -
    1. A view is bound to exactly one Node in the DOM
    2. In the future we may want to support views bound to other types of data structures (ie. flat files)
    3. As with components, views should be nameable
    4. Every view should be Cloneable
    5. Every view should provide an ElementFactory (for the view context; allows the model implementations to extract information from the DOM if necessary)
    6. Some components may require specific types of views which have added functionality (ie. TableView, TemplateView)
    7. Q's - Open issues...
      1. what about making views Serializable?
  4. View Context -
    1. A ViewContext is an object that encapsulates information about the context of the render request. Specifically, it must identify:
      1. Client capabilities
      2. The event context (if the request to render resulted from an event)
      3. The element factory
      4. The template node the current view is bound too
    2. The general idea is that when you want to render a component hierachy you must provide it with a ViewContext...this information may be needed by the component or the component's models in order to correctly render the component into a view
    3. Each component then will pass the view context information into each of its models prior to the component actually rendering

Specifics...

  1. Components - There are a number of specific components...
    1. BComponent -
      1. this component is the base class from which all other components must extend
      2. in terms of rendering, there is no visible representation of data (except for basic component visiblity)
    2. Components w/ Models -
      1. BList -
        1. Takes a ListModel
        2. Push-mvc approach to rendering--the component clears the view, then takes data from the model and pushes it in place
        3. The basic idea is to try and render the data into a list structure appropriate to the type of node to which the list is bound.
        4. Can be used to render into a variety of DOM elements: [TODO--link to list]
      2. BSelect -
        1. Extends BList, takes a ListSelection model in addition to the basic ListModel
        2. Uses this selection model to keep track of what's selected in the component
        3. Also provides the ability to specify the view size (ie. in the case of an HTML select element, how many rows are visible; if not set, render defaults this value to what's in the markup)
        4. Can be used to render into a variety of DOM elements: [TODO--link to list]
        5. Allow for any number of EventListener's to be notified when the underlying markup element is activated on the client (interfaces with Barracuda's event model to add event handler support)
      3. BTable -
        1. Takes a TableModel -OR- can take 2 table madels (for header, body, and footer, respectively)
        2. Push-mvc approach to rendering--the component clears the view, then takes data from the model and pushes it in place
        3. In practice, this has proved to be one of the least useful components (much easier just to use BTemplate with directives)
      4. BTemplate -
        1. Supports 1 or more TemplateModels, which are accessed by name
        2. Pull-mvc approach to rendering--instead of populating the view by looking at the model, the component instead processes the view looking for directives. When it finds a directive it attempts to map it to the appropriate model, which then returns some kind of data, and the template component figures out how to render it in view
        3. Only a very simplistic directive set should be supported:
          1. Get_Data (and add it as an element to the view)
          2. Set_Data (as an element attribute)
          3. Iterate_Start (start an iteration)
          4. Iterate_Next (move to the next item in an iteration)
          5. Iterate_End (repeat the current iteration)
        4. In many cases, a template model will not only return text but may very well return other complex Barracuda components (ie. BAction, BLink, BList, etc)
    3. Components w/out Models -
      1. BAction -
        1. Has a notion of an "Action" (either a URL or a Barracuda event) to be invoked on the client
        2. Should allow key/value parameters to be added onto this action (ie. as URL params when finally rendered)
        3. Should support the notion of disabling the back button [TODO--link to doc]
        4. Can be used to render into a variety of DOM elements: [TODO--link to list]
        5. Allow for any number of EventListener's to be notified when the underlying markup element is activated on the client (interfaces with Barracuda's event model to add event handler support)
      2. BLink -
        1. Extends BAction; used primarily to render "links"
        2. Adds notions of "link text" and "link target"
        3. Can be used to render into a variety of DOM elements: [TODO--link to list]
      3. BInput -
        1. Adds notion of Input type (Text, Password, Submit, Reset, File, Hidden, Image, Button, Radio, Checkbox)
        2. Adds the notion of Input value (ie. text to go in the input control)
        3. If either of these values are not set, the component rendering process defaults to what's in the template
        4. Can be used to render into Input DOM elements: [TODO--link to list]
        5. Allow for any number of EventListener's to be notified when the underlying markup element is activated on the client (interfaces with Barracuda's event model to add event handler support)
      4. BToggleButton -
        1. Extends BInput; used primarily to render toggle buttons (Radio, Checkbox)
        2. Adds notion of selected/unselected
        3. Can be used to render into Input DOM elements: [TODO--link to list]
      5. BText -
        1. Used to render text into a variet of DOM elements: [TODO--link to list]
      6. BScript -
        1. Used to ensure that a require script is available on the client
  2. Models - There are several distinct types of models...
    1. ListModel -
      1. Allows a component to iterate over a set of data
      2. Must return the size of the set
      3. Must return items based on position in the set
      4. Should be able to be "reset" to a pre-iterated state
    2. ListSelectionModel -
      1. Used to keep track of selected items in a list
      2. Supports notions of single and multiple selections
      3. Very similar to Swing's ListSelection model
    3. TableModel -
      1. Allows a component to iterate over a tabular set of data
      2. Must return the row count
      3. Must return the column count
      4. Must return items based on a row/col position in the set
      5. Should be able to be "reset" to a pre-iterated state
    4. TemplateModel -
      1. Must have a name (String data) to distinguish it from other models...directives will typically target a model by name
      2. Must provide a method for the model to determine whether or not it will process a directive (ie. based on view context)
      3. Must return data based on key name (String data)
      4. A template model may optionally implement IterativeModel if it services a collection of data
    5. IterativeModel -
      1. Provides a simple mechanism to iterate over a collection of data
      2. Defines 4 basic methods:
        1. preIterate
        2. hasNext
        3. loadNext
        4. postIterate
      3. When a template component renders, it may use these methods (in response to directives) to iterate over a collection of data in the model
  3. Views - There a also several distinct types of views...
    1. View - the default view class which is used for all components except BTemplate and BTable
    2. TableView - a view that can optionally be bound to multiple nodes (for header, body, and footer)
    3. TemplateView - extends the basic view to add support for template specific notions (ie. directives)

 


$Date: 2006-01-02 15:59:13 -0500 (Mon, 02 Jan 2006) $