Well, I (just about) finished implementing the new metadata
structure, so I went ahead and checked it in.  Sorry for the flood of
e-mail!  The basic architecture can be seen from the interfaces in
org/jboss/metadata:

Server
  +  Beans (namely, EJBs)
      +  Container
      +  Methods
      +  Home Methods
      +  Fields
IO
  +  XMLReader

        The only reason that Container is distinct from EJB is that it
reflects the underlying file structure - one set of container settings may
be shared across many beans.  We may choose to dispense with the Container
distinction if we change the file structure.  I put Container under Bean
instead of vice versa since whenever you're doing something in jBoss
you're doing it on a bean (perhaps on the home, but related to a specific
bean), so the Bean seemed to be a better entry point for the metadata.
        It is a little misleading to call the top level "Server", since it
truly just represents a collection of Beans sharing one set of
configuration files, so it would perhaps be more aptly named "Jar" or
"Application" - I'm open to suggestions.

        Anyway, when you deal with these interfaces, you use the
getProperty and setProperty methods.  All the metadata classes can hold
properties (though so far, a server doesn't have any).  All the properties
from all the files are addressed together.  So if you call
getProperty("foo") it doesn't matter whether foo was defined in
ejb-jar.xml, jboss.xml, or jaws.xml - which also means the properties must
be uniquely named across "plugins" - or configuration modules.  This
aggregation of properties is done by the classes in the
"org.jboss.metadata.aggregate" package.  So basically you load one reader
per plugin, and then have them all read into an aggregator which becomes
the implementation behind the MetaData interfaces you actualy use.
        The "io" package includes the XML reader interface, and will
eventually include more "visitors" that read in or write out the metadata
(or translate to GUI objects, etc).  It would be great to base this on a
more generic "Visitor" interface, but I couldn't think of how without
introducing lots of casting (help me!).
        The "plugins" package has the abstract base classes used by a
plugin module.  Right now, these automagically handle public, nonstatic
instance variables.  There's a movement to replace that with getters and
setters (or the equivalent), and I wouldn't object - I just haven't done
it myself.
        The "ejbjar", "jboss", and "jaws" packages are the plugins for the
three configuration packages we use so far.  They are not 100% complete -
I only used the settings in the files I was working from.  The major
omissions are resource references/managers (which may merit an
interface of their own), database data type tranlations (I contend this
should be at a server level not an application level), and stateful
properties (I didn't have any stateful beans).  If you see something I
missed, please add it in!

        Finally, there are two samples of use.  First, if you run the
class org.jboss.metadata.MetaDataFactory, you give it a directory, and it
will parse in the 3 XML files and dump the metadata to the console (it's
not very robust: for example, if one of the files isn't there).  Second, I
implemented the TxInterceptor using this metadata structure (see
org.jboss.ejb.plugins.TxInterceptor.getTransactionMethod).
        I made the requisite changes to container, container factory, etc.
to hold the new meta along with the old.  I'll start switching other areas
over to the new metadata once we work through any major changes to this
new architecture.

        So - what I need now is some feedback.  Take a look, let me know
what's on your mind.  I'm open to changes - I don't want to push this on
everyone - but I wasn't getting very far mailing code around privately and
I needed transactions to work to get anywhere with Oracle (which doesn't
save anything if you can't commit!).

Thanks, 
        Aaron


Reply via email to