[Dev] Schema API Status

Phillip J. Eby pje at telecommunity.com
Tue May 31 11:07:50 PDT 2005


The first phase of schema API integration is now complete; you can define 
schema as part of a Python class, and have it automatically merged with the 
schema defined in parcel.xml (with the parcel.xml definitions taking 
precedence, if there is a difference).

However, no parcels have yet had their schema moved.  I've done some work 
in my own checkout, moving all of the non-Block attributes of the 
ContentItem kind to the ContentItem class, and Chandler seems to work.  It 
looks as though we could begin the process of moving all Attribute 
definitions from parcel.xml to the corresponding Python modules.

Once I moved the attributes out of the contentmodel parcel.xml, it also 
became clearer what other features the Schema API is going to need to have 
in order to eliminate the remaining schema parts of parcel.xml:

    * Cloud definitions
    * Enumerations
    * Kind-level attributes (e.g. 'displayAttribute', 'examples', 'issues', 
etc.)

Mostly, these were already known about and discussed previously, but now 
it's a lot easier to see the specific use cases that need to be supported, 
once the already-supported features are removed.

As soon as the tinderbox is green again, I plan to check in the changes I 
have so far to the contentmodel tree of parcels.

Sadly, the process of porting existing parcels is a little bit 
tricky.  It's very easy to create new parcels with the Schema API, but to 
replace parts of parcels in a strongly connected web of existing parcels 
requires a little care not to break things.  Also, the current 
deeply-nested package layout forces additional work that wouldn't be needed 
with a flatter layout.

So here's the process that I've been following:

Step 1. Copy the <Attribute> blocks from the parcel.xml to the Python 
module where the class corresponding to that Kind is defined, and edit them 
to convert to a schema.One() or schema.Sequence() definition.  (Mostly, 
this consists of deleting extraneous XML markup.)

Step 2. If the module doesn't have its own parcel subdirectory, I have to 
take a couple of extra steps to ensure that the class gets loaded into the 
right parcel at runtime.  (This is an extra step caused by needing to match 
the existing parcel structure; if you were creating a new parcel, you 
wouldn't have to force-fit a particular parcel hierarchy.)  The extra steps 
are:

   a) Add a __parcel__ definition to the module containing the class.  For 
example, in the osaf.contentmodel.ContentModel module, I added this line:

          __parcel__ = "osaf.contentmodel"

      because the classes in the ContentModel module are actually part of 
the parcel corresponding to the "osaf.contentmodel" package.

   b) Add an import statement to the parcel's package, to import the class 
that should be part of the parcel.  For example, to make the ContentItem 
class available to the parcel, I added the following line to the __init__ 
module of osaf.contentmodel:

          from ContentModel import ContentItem

      This step is necessary because when the parcel loader references the 
ContentItem Kind in the osaf.contentmodel parcel, the schema API has to be 
able to find the corresponding ContentItem class, in order to merge their 
definitions.  It can't do this if ContentItem is hidden in a 
submodule/subparcel.

   Of course, neither of these steps would be necessary if references to 
the ContentItem kind and class weren't already spread out all over 
Chandler.  We could either decide that osaf.contentmodel.ContentModel is a 
valid parcel unto itself, or conversely we could move the class definition 
up to the __init__ module, and either way it would work just fine.  I 
expect that for parcels which do not contain any data items, the common 
thing to do will be to just directly reference the module containing the class.

Step 3.  Run lots of tests, start Chandler with a new repository, check the 
repository, inspect stuff in the repository viewer, etc. etc.

Step 4.  Repeat.  :)  (from Step 1, I mean)


So, there's a long process of migration ahead, mostly because this should 
be taken in moderately-sized chunks to allow testing to verify correct 
operation of the changed parcels.  The actual migration steps (1, 2a, and 
2b) are really fast and easy, so if we wanted to do a "big bang" migration 
we could probably do it quite quickly.  I think I'd like to start slow, 
however, and maybe if things go well for a while with the first few 
batches, we can jump in and do the rest.

While I'm waiting to see if any bugs come back from those first ports, I'll 
work on implementing the additional features needed to migrate the 
non-Attribute parts of parcel.xml schema definitions, so that we can 
migrate those out as well.  Also, I'll work on adding support for defining 
items in Python as well, so that parcels with only a few items to define 
can do so without needing to have a parcel.xml at all.

Once all of the schema Kinds are hooked up with their corresponding classes 
in the Python source code, some other interesting things will become 
possible.  For example, I understand that the 'itemClass=""' attribute is 
used quite frequently for UI items so as to avoid needing to define 
distinct Kinds.  However, as soon as the classes involved are linked to the 
parcel loader, they will already *be* Kinds, so instead of using 
'itemClass' you can just use the class' name as the element name, as if it 
had its own Kind definition already.

There will also be considerable opportunity to simplify code that now has 
to deal in Kinds and views, but in future will be able to just use classes 
directly, and/or not care about the view.  There will also be an 
opportunity to consolidate the constructor signatures of various families 
of Item subclasses, to create a more consistent developer API for creating 
those items.

But going back to the immediate state of things; I'll be checking in some 
initial changes to just parts of the osaf.contentmodel parcel, as soon as 
the tinderbox is green again.  I'd encourage everyone to look at the diffs 
as these changes go in, so that you can get a quick feel for how to port 
various kinds of features, and to email me or ping me on IRC with any 
questions you might have, or if you find any problems.  Thanks.




More information about the Dev mailing list