ansutton at kent.edu
Fri Mar 21 09:39:08 UTC 2003
umbrello2 now has a mostly functional and absolutely generic xmi parser. it's
actually very well commented so it should be fairly accessible. i still need
to clean up some debugging code, but it's all good. i also need to write some
fixes to implement some minor differences between the MOF metamodel spec and
the UML/CWM metamodel spec. however, these should relatively benign.
here's how it works - if anybody's interested. we grab an XML document and
pass it to Xmi::Reader::read(). it grabs some of the <XMI.header>
information. actually it skips the documentation for the time being, but it
does look for the <XMI.model> and <XMI.metamodel> tags. the metamodel tag is
really important. When the metamodel tag is found, the parser turns the name
into an Umbrello friends plugin name (i.e., libu2_model) and has the plugin
loader load the plugin. this means that we support dynamic loading of
metamodels at storage level - it also means we can have multiple metamodels
in a single XMI document.
when we parse the contents, we basically call out to metamodels that were
loaded as a result of <XMI.metamodel> tags. this is the only dependence of a
the XMI parser on metamodel implementations. i needed a simple way to
construct an object (derived from RefObject) and get access to association
information (anything derived from RefAssociation). based on those returns
and alot of the reflective interface (particularly RefFeatured::refGetValue()
and RefPrimitive::refSet()), we can generically assign the values XML
attributes to the RefObjects created during parsing.
associations are done in a similar manner. when we encounter a reference
attribute in the document, we can find the associated RefAssociation object.
we also return the position of the reference name as a boolean value
(isFirst). this is so we can put objects in the right positions when calling
out to RefAssociation::refAddLink(). works great - i think.
the entire system works on a set of 3 stacks. one stack contains the object
being configured, another stack contains the end of an association - i.e.,
the owner of reference features. the third stack contains the current
association and the position of the feature being parsed (first or second
Because XMI uses id's for references, i had to be careful about referencing
certain objects. as a result, we have this deferred reference resolution
system - quite clever if i say so :) if we find an xmi.idref pointing to some
object that hasn't been created yet, we simply push the current association
end, the current association information and the DOM element defining the
unresolved reference into a derred list. after all the parsing is done, we
resolve deferred references. this is actually really simple. we just push the
association end back onto the stack, the association info and re-parse the
object. works great.
there may still be some reflective issues that i need to take care of like
setting the MOF id or reference counting all the objects. i don't know, we'll
see. oh - and definitely metaobject stuff (return values from
what's up next... well, there's a couple of things... it's great that i can
read an XMI document, but i'm not doing anything with it. i need to create an
Umbrello::Model class that contains objects instantiated during parsing. this
means that a metamodel plugin can expose a reference to its actual metamodel
- its parsed XMI spec file. this would also be the basis of containing UML
models. i'd also like to *see* what i'm generating so i want to create a
metamodel view. it's basically a treeview that shows elements in a tree,
based on their containment (like a class view). i'd like to build it as a
plugin to umbrello - any suggestions on this?
More information about the umbrello-devel