A few weeks back I made a post about the first version of universal expression language for wicket. Since then it's come quite a way. The initial version hooked into by implementing IMarkupResourceStreamProvider for markup owning MarkupContainers (Panel, Page etc...) and by regenerating markup fragments for markup receiving MarkupContainers (ListView). Unfortunately due to the fact that the EL expressions need to be evaluated on every request this meant a huge performance hit (about 75% less than standard wicket) due to forcing wicket to constantly parse markup on every request cycle.
The current evolution of wicket-el hooks in very differently. My first preference was to create a dynamic version of Markup and MarkupFragment that replaces MarkupElements that contain EL expressions with a dynamic version. Unfortuantely this was impossible because I need to subclass Markup (wicket uses a few case of 'instanceof Markup') and Markup has many final methods. And simply wrapping all the MarkupElements isn't possible because RawMarkup is a final class and is also reference inside wicket with 'instanceof'. So the only way I could think of to do it (which I've done and it works) is to create a subclass of Markup (ModifiableMarkup) that takes the original wicket-parsed markup, and adds all it's elements. Then during the onRender phase EL enabled components call ModifiableMarkup.resolve(ExpressionResolver, ELParseMatchList) which internally replaces RawMarkup elements belonging to that compenent with an EL resolved version. This is done just before calling super.onRender(). Sounds ugly but it works and performance is now equal to standard wicket (in some cases can even be a little faster due to not needing PropertyModels). Because the Markup instances are now mutable I can't use wicket's markup cache as it's one per class and ModifiableMarkup.resolve method could easily be called by many threads at once. So I've had to implement caching per thread/class combination. i.e. ELPanel will have a cached instance of Markup for every thread. My question is twofold: 1/ As I have no choice but to leave ModifiableMarkup mutable, what is the purpose of making Markup immutable? From what I can see from browsing wicket source all it achieves is a bit of safety and releasing some resources from the backing XmlTags in the MarkupElements. Is there any other purpose to it? i.e. can you forsee any problems with using a mutable instance of Markup for rendering? 2/ Is the per thread/class caching strategy really safe? The only way I could think it could be broken is if it was possible for the server to suspend a thread mid-render cycle and give another request use of that thread. If that happened the new request would overwrite the markup expressions and the when the old resumed and expressions already resolved would have values from the the request that interrupted it. As far as I'm aware with the work I've done with Jetty and NIO connectors before this will only happen if you ask Jetty to do it while processing the request. Is this a possibility with wicket or can I rely on a complete render cycle to happen uninterrupted before the thread is reused for another request?
