GWML: XML Schema for the GW Intermediate Representation
We defined the GWML. The first and most complete specification can be found in doc/gwmlformat.txt. In src/gwml/definition you can find three subdirectories containing a file per tag for each of the languages twiki, gwml and xhtml. It is automatically tested in the GWMLDefinitionTest that these files indeed are mapped to one another. Because the GWML (which is an extension of XML) uses a special namespace it is in fact possible to map to and from gwml without the loss of information.
Parsing TWiki Markup
We are able to parse most Twiki markup. The idea to use a context-free grammar to actually parse the Twiki has, however, proven to be very complex. The Jflex/Cup combination we used is not nearly powerful enough to express or solve ambiguities. This has resulted in a pretty nasty .cup file. Unfortunatly we spent a large portion of our time in exactly this area. For a specification of which tags we can currently parse please take a look at the tests and the gwml definition (which is automatically verified to work in the tests). Solutions for the future are either to use SDF or to use regular expressions as in the very first version and parse the resulting XHTML using an off-the-shelf DOM-parser.
Rendering: GWML representation to HTML in XSLT
This requirement is satisfied completely. XSLT is split up into appropiate files in a library. These files include and import each other when necessary. The right template is located based on the directory one is currently in, that is, for specific parts of the wiki one can define specific stylesheets.
Cascading Stylesheet: pretty layout
We didn't work on this requirement due to our overwork at the parser.
Templates provide context for generated HTML
The template for view has a few examples of status bars.
The right template is located based on the directory one is currently in, that is, for specific parts of the wiki one can define specific stylesheets.
Rendering is based on the type of file (as indicated in the subversion repository). It is possible to define different StyleSheets, depending on the type of file you want to render. The default StyleSheet just forwards the file as a binary.
Context variables are supported using the format variable:///variablename?attribute1&attribute2
One can implement the interface VariableHandler to describe how the URIResolverImpl should display this variable. These VariableHandlers should be registered at the URIResolverImpl. A small number of variables has been implemented by us both as a proof of concept and for our use. Other groups have been notified of the existence and usage of this variablehandler.
Access Control is implemented in a very simple way: if an exception is thrown because an attempt has been done to illegally access a file we just pass it on in ShowFile.
Caching has proven to be pretty difficult. A naïve approach would be to simply cache StyleSheets and apply the StyleSheet with a specific URIResolver. This, however, is impossible, since (a) the StyleSheet as provided by the vendor does not support this kind of behaviour and has only one fixed URIResolver per StyleSheet and worse (b) the StyleSheet itself is built based on imports which are based on the URIResolver. A solution should indeed keep a complete list of dependencies.
Integration with Forms
The Forms group has never contacted us and seems not to have merged with the trunk
gives a pretty accurate overview of the things we did and at which times we did them. It does, however, not speak explicitly about a number of things that were so “normal” to us that we did not write them down.
We implemented roughly 80 tests. Most of these deal with parsing, which is partly indicative of the amount of effort and time we spent dealing with parsing. It is also caused, however, by the fact that most of our other code is more abstract: it deals with supporting an architectural pipeline, while the parser can be very clearly expressed in pairs of input and output. The tests have been pretty useful in our Software Engineering process. We've spent nearly none of our time debugging and most of our time actually coding. At a number of occasions they pointed to code we had just broken so it could be fixed immediately. Another benefit was that we didn't need to use the entire Jetty/Browser combination to check whether things were working which is simply a great time saver: the server didn't have to be restarted every minute and we never had to worry about browsers caching the wrong files etc. If we decide to change the parser technology the current tests can be used as an automatically checked specification.
We've spent most of our programming time as pair-programmers. The times which have not been spent in that way can be looked up in the RATLog
and have indeed been proved to have been significantly less productive. Some simple tasks have however been done alone which was a good choice. Pair programming has also been useful in propagating knowledge about the design and in keeping up our practices. Another thing: at almost all times the team was working very close to each other and always in the same room. We've also experienced some challenges: when pair-programming with two people of different capabilities it is very important to switch tasks between the “driver” and the “navigator” because the driver is much more likely to do all the typing. Another obstacle has been the lack of attendance of some of our team members at times.
We've practices continuous integration between sub-project members at all times and with the entire project from somewhere halfway. This was a good choice: merging with the trunk had been a minor bump, although the alternative: all sub-projects starting together was not viable at the time. At one occasion one of the team members did not commit because the code was broken. This has resulted in the straight-out loss of that code.
- We Refactored a lot and at low cost – our IDE (eclipse) supports easy refactoring. This has helped us to keep an overview of the code.
- We had CollectiveCodeOwnership: anyone who saw something he didn't like was obliged not to complain but solve the problem himself – it was his code after all.
- We didn't spent an extra effort keeping the design extra simple for reasons of Extreme Programming: the architecture was pretty much determined by the customer.
- A CodingStandard has helped us to keep the code clean.
We experienced JIRA to be a drag on development in the current setting. All 30 people were together anyway so oral communication was much smoother. Furthermore JIRA doesn't allow for quick entry of a great number of Features and was mostly out of sync with actual development.
We (including the customer) made (with hindsight) two mistakes:
- We should never have started with the TWiki Language but just have defined the GWML
- We should never have tried the old-fashioned CUP techniques to do reasonably complicated things
At some times, especially in in early monday mornings not that many people where there. Rendering as a group was certainly not the least active group, but it remains that it's annoying to have to work alone in a cold concrete building on a gray day.
Physical enviroment & machines
We had some trouble with our environment
- At some times (until we asked Eelco Dolstra to solve this for us) nix was somehow out of sync so we couldn't use some of the lab-machines.
- The Dutch National Programming Championships destroyed all Linux machines for the first three hours last monday
- It was frustrating to have to spend the first fifteen minuten of the monday morning trying to get the rooms to be openend but finding no-one.
Integration with other teams
Integration with the other teams was problematic at some times. We had a working framework fairly early on. The query-group has asked us for functionalities a number of times. About a week before the deadline we implemented and explained the VariableHandler interface especially for them but they didn't use it in the end. Versioning was the most likely candidate to make heavy use of the rendering interface. They didn't want to use our pipeline since it wasn't fully operational yet. In the end we did manage to merge a number of our results, but there is still a lot of versioning code that outputs HTML in java. Offcourse we make heavy use of the Storage interface. This proved to be trivial.