This page contains some brief notes on the design of XMLC automatic page recompilation.
An implementation of automatic class recompilation was developed by a user that created classes with names containing time stamps. This allowed new versions of the class to be loaded in he same class loader. Interface were generated for the classes. They were loaded and recompiled by a factory. This approach was not used because:
It is possible to load a recompiled class in another class loader and then return a reference to an object of this class as the interface. This was prototyped by creating a new class loader per recompiled class. However, this is problematic for derived classes. Since the derived class is not recompiled, its not desirable to load it in a new class loader. However this is required, since once the XMLC class loader calls another class loader to load the derived class, there is not way to get back to the XMLC class loader.
It's possible to only load the class hierarchy of the derived class down to the compiled class by examining the hierarchy of the old class and restricting a class loader to load just these classes. This will allow a override DOM building mechanism to continue to work.
This implementation suffers from complexity. Additionally, there is no way to query the inheritance structure without loading it (unless some parsing code is added). Since one has to load the class initially without a filter to know the structure of dependent class there is no control over where the dependent classes are loaded. If the class loader is not the primary class loader for the application, classes maybe loaded into the wrong class loader, causing sharing problems.
The generated class could re-parse out-of-date files when detected instead of generating the file with compiled code. The performance penalty would occur only when the class is loaded.
However the class must be recompiled to validate the HTML file against the
interface and provide a compiled class the next time the page is loaded,
so why not get it from that class? The DOM could be obtained directly
from an instance of the recompiled class and stored in the
out of date class. The syncAccessMethods()
method would then
initialize the pointers to the access methods.
The big drawback of this approach is that its difficult to do override DOM building. The delegation approach is similar and allows override DOM building to work.
Loading the recompiled class in another class loader and having the objects of the old class delegate method calls to objects of the new class. Doing the delegation on method would require adding checks in every method in the base class and the derived class. Not a lot of overhead, but must be done by all base-class and generate class methods.
The big disadvantage with this approach is that override DOM building is a bit complex to delegate. A way of implementing this is by having an instance of the recompiled class point back to the instance of the out-of-date class. Creation methods in the instance of the old-of-date class call the recompiled class creation method through the delegate pointer. The newer creation method does its thing, however when it calls another creation method, that is done by calling the method in the older class. This method in the old class will immediately call the creation method the recompiled class. This allows these methods to be overridden. It also insures that the order of calling creation methods is defined by the recompiled class, not the out-of-date class.
So lets say we have the part of a page being:
<TABLE ID=Fred> <TR ID=Row1>..... ... </TABLE>Under the override DOM build approached, this would generate a method
createElementFred()
which would call
createElementRow1()
. The generated code would look something
like this:
HTMLTableElement createElementFred() { if (delegate != null) { return delegate.createElementFred(); } else { HTMLTableElement elem = document.createElement("TABLE"); if (delegator != null) { $elementRow1 = delegator.createElementRow1(); } else { $elementRow1 = createElementRow1(); } if ($elementRow1 != null) { elem.appendChild($elementRow1); } } }Note that
$elementRow1
is the field used by the access method.
This has the disadvantage that the creation methods must be public, rather than protected, which might be confusing.
.xmlc
extension.
If is currently an XMLC options file, but will be an XML
file in a future release.
XMLCAutoCompFactory
. The instance is requested
either by specifying a class name, an interface class or the
class itself. This can be the XMLC generated class name or its
interface or a derived class or its interface. If an interface is
specified, the implementation name is generated by appending
Impl
.
MultiClassLoader
,
which can either be the class loader that loaded the supplied
interface or a MultiClassLoader
supplied to the
factory.
XMLCAutoCompFactory
object
which contains the class information and
MultiClassLoader
Resource
object for
the class and source file. The Resource
contains
the methods necessary to check file update time.