The Subversion Object Model --------------------------- Content ======= * Context * Requirements * The Plan * Documentation * Testing * Drawbacks * Guidelines * Object Model Outline * Notes Context ======= One of the points that the Subversion project has historically prided itself on is the ease with which it interfaces to other languages. We provide support for bindings in ruby, perl, python, and java, while third parties develop bindings for C++[1], C#[2], Objective-C[3] and other languages[4]. Every single one of these sets of bindings uses a different object model, or none at all. For instance, the in-tree python bindings are largely generated by SWIG[5], but we do not provide anything more in the way of a more "pythonic" object-oriented interface. Though each of the possible target languages has different idioms, we can define a common object model for the underlying libraries which presents the Subversion API in a unified manner, regardless of the language chosen. This model shall hereafter be referred to as the Subversion Object Model (SOM). Such an object model presents a unified interface for developers in all bindings languages, and allows for a single, language-agnostic set of documentation. Several other projects have successfully implemented such a model, inclding wxWidgets[6] and MapServer[7]. There have even been past proposals within Subversion[8], but no real progress has been made. (The exception is the python c-types bindings[9], which have yet to be merged to trunk.) Requirements ============ Some general requirements for the object model, and the language bindings which implement it: * Easy and complete document (see Documentation, below) * Common tests (see Testing, below) * Dedicated maintainers * Thorough coverage of the relevant libraries (These aren't hard-and-fast requirements, just ideas.) The Plan ======== The general plan for implementing this is as follows: 1) Document the entire object model, including all APIs. 2) Create a "reference implementation" preferrably in C++, because it relatively easy to wrap C code with. (We may even be able to borrow code form TortoiseSVN or rapidSVN, depending on licensing.) 3) Create unit tests. 4) Lather, rinse, repeat for other languages. We may be able to use SWIG to help generate the code for other languages, or just place the object model layer on top of the current SWIG bindings. We could do each of the above steps on a per-library basis, or for the entire project as a whole. If done per-library, we may want to do the client library first, as it is currently the library which most third-party bindings packages provide the most coverage of. The first library done would probably take the longest, due to ramp-up costs in wrapping much of libsvn_subr. Documentation ============= One of the benefits of using an common object model across different languages is that they could share documentation. Indeed, both of the projects mentioned above, wxWidgets and MapServer, have generic documentation for their various interfaces. One of the problems they face (and we would too) is how to generate those docs. It is both impractical and unwise to abandon the Doxygen documents currently in our C header files, but these do not acurately reflect an object model. We may be able to use Doxygen's XML output to initially generate some of the documentation from the C header files, but the object model docs would probably need to be maintained independently of the C headers. This may be a lot of work. In a perfect world, the documentation should be the place where we specify what the object model will be, and should be completed *before* any code is actually written. Testing ======= Because each of the bindings would use the same model, it would be reasonable that they could use the same tests. Ideally, we could write the tests in some sort of abstract testing language, which could then get compiled to language-specific tests. This would allow "write once, run many" tests, which could apply to all the bindings surfaces. Unfortunately, I don't yet know of any such testing language or tool. Until such time as one exists, we may want to port existing language-specific tests to the new object model. Drawbacks ========= There are drawbacks to a common object model for the Subversion bindings languages. These include: * Maintenance - Both of code and documentation. (Hmm, but we already *do* have separate docs, at least for the JavaHL bindings...) * Tool support - Some of the automated tools discussed above either don't work well, or just don't exist. * Compatibility - Do we drop support for exist bindings in favor of the object-model based ones? Is this a "2.0" type of project? Guidelines ========== Some proposed guidelines for translating Subverion's C header files (subversion/include/svn_*.h) into a wrapper language's object model include: * C modules define a Java package, Python module, etc. * Module functions and callbacks should be methods of an interface/mix-in. * Batons are opaque data structures, and can be represented as empty interfaces or callable objects. Contexts are generally represented as class state. * In languages for which it is applicable, returned svn_error_t's should be declared as thrown exceptions. Object Model Outline ==================== A brief description of the proposed object model. This is *not* a comprehensive specification, we anticipate that such a spec will be part of the API documentation. Modules: * Client * RepoAccess * Repository * FileSystem * WorkingCopy Notes ===== [1] http://rapidsvn.tigris.org/ is one example. Others are maintained independently by TortioseSVN (http://tortoisesvn.tigris.org/), and probably others. [2] http://www.softec.st/en/OpenSource/ClrProjects/SubversionSharp/SubversionSharp.html [3] http://scplugin.tigris.org/ maintains an Objective-C interface layer. [4] See http://subversion.tigris.org/links.html#bindings for a more complete list. [5] http://www.swig.org/ [6] http://www.wxwidgets.org/ [7] http://mapserver.gis.umn.edu/ [8] http://svn.haxx.se/dev/archive-2003-10/0215.shtml [9] http://svn.collab.net/repos/svn/branches/ctypes-python-bindings/