Java Beans XMLEncoder Proposal
or Proposal to Abandon Spring
What does Spring do for us? The only feature we've used so far is an easy way to construct a bean tree from XML. The other useful affordance of Spring, its raison d'etre, is dependency injection. We haven't used that yet and we may not need to. I'll try to think and write more on that, but for now let's consider the bean construction.
If that's all we're using Spring for, the java.beans.XMLEncoder class is a much better way to go. It's what it was designed for. It aligns with all the existing Java Beans tools. It means we have the support of Sun. It uses more of the affordances of the Java world.
How would we go about switching? Well, with XMLEncoder everything must be a Java bean. In our curnit.xml, a podule is a sort of Java bean but it's lexically different (<podule> element). Using XMLEncoder, a podule would be a proper Java bean. What would set it apart is implementing the sail.beans.Podule interface.
package sail.beans; public interface Podule extends Serializable { public void setPoduleId(String poduleId); public String getPoduleId(); public void setPoduleName(String poduleName); public String getPoduleName(); public void setPoduleChildren(List podules); public List getPoduleChildren(); }
Basically, we define three standard properties for Podule beans:
- poduleId - fixed id for reference to the podule within and outside the curnit
- poduleName - human label (maybe should be called poduleLabel)
- poduleChildren - other podules which of which this one is the parent. When this podule is copied somewhere else, the children come along.
Spring-based Curnit XML
We handle these in our current curnit XML
- poduleId is an @id attribute on each <podule> element
- poduleName is a @name attribute
- poduleChildren are encoded by embedding other <podule> elements within (as DOM child nodes)
This is the current curnit representation for "WISE Example 1", with one modification. I've added the "poduleChildren" as an explicit property to the beans. I needed this set in the bean so I could dump it into the XMLEncoder-based curnit XML.
<?xml version="1.0" encoding="utf-8"?> <curnit> <podule class="sail.beans.wise.WiseProject" id="root" name="Pedraw testing" icon=""> <property name="poduleChildren"> <list> <ref local="activity40"/> <ref local="activity41"/> <ref local="activity222"/> </list> </property> <property name="title"> <value>Pedraw testing</value> </property> <property name="activityList"> <list> <ref local="activity40"/> <ref local="activity41"/> <ref local="activity222"/> </list> </property> <podule class="sail.beans.wise.WiseActivity" id="activity40" name="Basic" icon=""> <property name="poduleChildren"> <list> <ref local="step125"/> <ref local="step126"/> <ref local="step127"/> </list> </property> <property name="title"> <value>Basic</value> </property> <property name="stepList"> <list> <ref local="step125"/> <ref local="step126"/> <ref local="step127"/> </list> </property> <podule id="step125" class="sail.beans.wise.steps.Pedraw" name="No stamps" icon=""> <property name="title"> <value>No stamps</value> </property> <property name="parameters"> <map> <entry key="filename"> <value>default</value> </entry> <entry key="startwithFilename"> <value/> </entry> <entry key="html"> <value>No stamps</value> </entry> <entry key="stamps"> <value/> </entry> <entry key="backgrounds"> <value/> </entry> </map> </property> </podule> <podule id="step126" class="sail.beans.wise.steps.Pedraw" name="With stamps" icon=""> <property name="title"> <value>With stamps</value> </property> <property name="parameters"> <map> <entry key="filename"> <value>default</value> </entry> <entry key="startwithFilename"> <value/> </entry> <entry key="html"> <value>With stamps</value> </entry> <entry key="stamps"> <value> Object </value> </entry> <entry key="backgrounds"> <value/> </entry> </map> </property> </podule> <podule id="step127" class="sail.beans.wise.steps.Pedraw" name="With 1 background" icon=""> <property name="title"> <value>With 1 background</value> </property> <property name="parameters"> <map> <entry key="filename"> <value>default</value> </entry> <entry key="html"> <value/> </entry> <entry key="backgrounds"> <value> Object </value> </entry> <entry key="stamps"> <value> Object </value> </entry> </map> </property> </podule> </podule> <podule class="sail.beans.wise.WiseActivity" id="activity41" name="old Wisedraw" icon=""> <property name="poduleChildren"> <list> <ref local="step137"/> <ref local="step305"/> </list> </property> <property name="title"> <value>old Wisedraw</value> </property> <property name="stepList"> <list> <ref local="step305"/> <ref local="step137"/> </list> </property> <podule id="step305" class="sail.beans.wise.steps.DisplayPage" name="test display page" icon=""> <property name="title"> <value>test display page</value> </property> <property name="parameters"> <map> <entry key="html"> <value><b>this is a display page</b></value> </entry> </map> </property> </podule> <podule id="step137" class="sail.beans.wise.steps.Generic" name="Simple" icon=""> <property name="title"> <value>Simple</value> </property> <property name="parameters"> <map/> </property> </podule> </podule> <podule class="sail.beans.wise.WiseActivity" id="activity222" name="With revisions" icon=""> <property name="poduleChildren"> <list> <ref local="step747"/> <ref local="step748"/> </list> </property> <property name="title"> <value>With revisions</value> </property> <property name="stepList"> <list> <ref local="step747"/> <ref local="step748"/> </list> </property> <podule id="step747" class="sail.beans.wise.steps.Pedraw" name="Draft" icon=""> <property name="title"> <value>Draft</value> </property> <property name="parameters"> <map> <entry key="filename"> <value>draft</value> </entry> <entry key="startwithFilename"> <value/> </entry> <entry key="html"> <value>you'll be drawing your draft now</value> </entry> <entry key="stamps"> <value> Object Object </value> </entry> <entry key="backgrounds"> <value/> </entry> </map> </property> </podule> <podule id="step748" class="sail.beans.wise.steps.Pedraw" name="Revision" icon=""> <property name="title"> <value>Revision</value> </property> <property name="parameters"> <map> <entry key="filename"> <value>revision</value> </entry> <entry key="startwithFilename"> <value>draft</value> </entry> <entry key="html"> <value>now revise what you drew</value> </entry> <entry key="stamps"> <value/> </entry> <entry key="backgrounds"> <value/> </entry> </map> </property> </podule> </podule> </podule> </curnit>
XMLEncoder-based Curnit XML
I made this by calling (new XMLEncoder(outputstream)).encode(launched) where launched is the root podule that implements Launchable.
The podule properties are now bean properties of the podule bean (which implements sail.beans.Podule): poduleId, poduleName, poduleChildren.
Properties the podule makes use of are there too.
What's not there are the transient properties because I marked those with "transient" in the code.
<?xml version="1.0" encoding="UTF-8"?> <java version="1.4.2_06" class="java.beans.XMLDecoder"> <object class="sail.beans.wise.WiseProject"> <!-- properties for all podules --> <void property="poduleChildren"> <object class="java.util.ArrayList"> <void method="add"> <!-- notice that this makes an idref to WiseActivity0, created within the activityList property. It would be nice if the original went here and the reference went there, but no real difference. --> <object idref="WiseActivity0"/> </void> <void method="add"> <object idref="WiseActivity1"/> </void> <void method="add"> <object idref="WiseActivity2"/> </void> </object> </void> <void property="poduleId"> <string>root</string> </void> <!-- two properties that WiseProject needs --> <void property="title"> <string>Pedraw testing</string> </void> <void property="activityList"> <object class="java.util.ArrayList"> <void method="add"> <object id="WiseActivity0" class="sail.beans.wise.WiseActivity"> <void property="stepList"> <object class="java.util.ArrayList"> <void method="add"> <object id="Pedraw0" class="sail.beans.wise.steps.Pedraw"> <void property="title"> <string>No stamps</string> </void> <void property="poduleId"> <string>step125</string> </void> </object> </void> <void method="add"> <object id="Pedraw1" class="sail.beans.wise.steps.Pedraw"> <void property="title"> <string>With stamps</string> </void> <void property="poduleId"> <string>step126</string> </void> </object> </void> <void method="add"> <object id="Pedraw2" class="sail.beans.wise.steps.Pedraw"> <void property="title"> <string>With 1 background</string> </void> <void property="poduleId"> <string>step127</string> </void> </object> </void> </object> </void> <void property="title"> <string>Basic</string> </void> <void property="poduleChildren"> <object class="java.util.ArrayList"> <void method="add"> <object idref="Pedraw0"/> </void> <void method="add"> <object idref="Pedraw1"/> </void> <void method="add"> <object idref="Pedraw2"/> </void> </object> </void> <void property="poduleId"> <string>activity40</string> </void> </object> </void> <void method="add"> <object id="WiseActivity1" class="sail.beans.wise.WiseActivity"> <void property="stepList"> <object class="java.util.ArrayList"> <void method="add"> <object id="DisplayPage0" class="sail.beans.wise.steps.DisplayPage"> <void property="title"> <string>test display page</string> </void> <void property="poduleId"> <string>step305</string> </void> </object> </void> <void method="add"> <object id="Generic0" class="sail.beans.wise.steps.Generic"> <void property="title"> <string>Simple</string> </void> <void property="poduleId"> <string>step137</string> </void> </object> </void> </object> </void> <void property="title"> <string>old Wisedraw</string> </void> <void property="poduleChildren"> <object class="java.util.ArrayList"> <void method="add"> <object idref="Generic0"/> </void> <void method="add"> <object idref="DisplayPage0"/> </void> </object> </void> <void property="poduleId"> <string>activity41</string> </void> </object> </void> <void method="add"> <object id="WiseActivity2" class="sail.beans.wise.WiseActivity"> <void property="stepList"> <object class="java.util.ArrayList"> <void method="add"> <object id="Pedraw3" class="sail.beans.wise.steps.Pedraw"> <void property="title"> <string>Draft</string> </void> <void property="poduleId"> <string>step747</string> </void> </object> </void> <void method="add"> <object id="Pedraw4" class="sail.beans.wise.steps.Pedraw"> <void property="title"> <string>Revision</string> </void> <void property="poduleId"> <string>step748</string> </void> </object> </void> </object> </void> <void property="title"> <string>With revisions</string> </void> <void property="poduleChildren"> <object class="java.util.ArrayList"> <void method="add"> <object idref="Pedraw3"/> </void> <void method="add"> <object idref="Pedraw4"/> </void> </object> </void> <void property="poduleId"> <string>activity222</string> </void> </object> </void> </object> </void> </object> </java>