cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Larson <>
Subject [cforms] Forwarding: Explanation of "dynamic stuff in form model"
Date Mon, 05 Jan 2004 15:32:18 GMT
[Forwarded from email discussion with Marc.]

I will try to explain the static and dynamic aspects that
were added to cforms with class/new and union.  Please let
me know any areas this does not clear up for you.

Class/new in the form model:
  A *general* utility to allow for widget definition reuse.
  It is not at all specific to the dynamic stuff in the form
  model, but just happens to also be useful for that application.

Union in the form model:
  Please see the sample form model design GUI for an example
  of its use.  The widget definitions are handled in the normal
  static way at definition building time.  The difference is the
  widget instances are created on demand at runtime (this is the
  "dynamic stuff in the form model").  Note that this non-recursive
  use does not require class/new.

Recursive form models:
  If we combine the features of class/new and union we can
  statically specify theoretically infinitely recursive forms,
  where the actual recursive depth is controlled by the data
  that is present, such as required to create form-based GUI's.

    A class that contains a "new" reference to itself would
    specify an unlimited recursive definition.  A smart builder
    would notice that the class contains a reference to itself
    and would substitute a simple Java object reference to the
    first (and only) definition it built to represent the class.
    With this trick we do not run out of memory attempting to
    re-create the class definition inside itself over and over.

    So we have no problems until we try to create an instance
    from this class definition.  The instance of the class
    cannot use the object reference trick to handle the infinite
    recursion, because each nested instance needs to have its
    own data.  Therefore the simple recursive class definition
    cannot be instantiated on finite physical hardware.

    Since we only have trouble with the instance, we only need
    to introduce dynamic behavior in the instance.  Notice that
    the definitions are never dynamically created or modified.
    The only dynamic activity is the act of choosing when to
    create instances from the definitions.

    We need a way to delay creation of the nested instances
    until they are actually required, which implies we need a
    way to indicate or determine when the nested instances
    become required.  This indicator could be stored in a normal
    widget to give us all the things a widget gives, such as
    binding, validation, and user interaction.  While we could
    use a boolean (required/not-required), why not make it a more
    general selector that indicates which nested instance from
    a set of options is currently required.  This is what was
    implemented as the Union widget.  Maybe it should have been
    called the "Selector" widget instead?

    The rest of the interaction between class/new and union is
    just to catch non-terminating recursion caused by form design
    errors where class/new and union were not used appropriately
    as described above.  No use allowing the server to fall over
    with out-of-memory errors if we can catch the problem early.

Dynamic behavior in form bindings and templates:
  The recursive forms described above still need bindings to
  load and save their data and templates to present their data
  to the user.  This forces us to mirror the class/new and union
  concept to the binding and template implementations.
  Like the definition handling above, the bindings and templates
  can be statically specified just as they normally are, with
  just the object reference trick added to the building process
  to prevent infinitely recursive building.
  The dynamic selection of bindings or templates to process is
  controlled by "union" bindings or templates which are driven by
  the actual data being loaded or the data in the form being
  saved or templated.  Notice that the bindings and templates
  are never dynamically created or modified.  The only dynamic
  behavior is the choice of when to invoke the bindings or
  templates to perform their binding or templating.

The "static final" issue with the model, binding, and template:
  The way class/new resolution currently works prevents the use
  of the "final" modifier because the last build step, resolve(),
  acts like a linker, replacing each "new" references to a
  "class" with references to the definitions, bindings, or
  templates contained in the referenced class.  Note that this
  all occurs at build time, and the definitions, bindings, and
  templates are are never modified after the build is completed.
  Also note that the definitions, bindings, and templates are
  created only once (when their containing class is built) and
  they are then only *referenced* with Java object references
  into each place where the class is referenced by "new".

  As described above, the only places were there is dynamic
  behavior is in the choice of when to create widget *instances*,
  when to call bindings, and when to perform templating.  The
  definitions, bindings, and templates themselves are completely
  *static* (never modified) after they are first built.

  There are various techniques we could use, such as the DOM
  tree processing you described, to allow us to use the "final"
  modifier.  I am not totally convinced (yet) that it is worth
  the effort to satisfy the compiler, or that the subtle resolving
  issues will be easy to address.

Hope this adds clarity,
--Tim Larson

Do you Yahoo!?
Find out what made the Top Yahoo! Searches of 2003

View raw message