Funny how the most difficult questions are the simplest ones to state...
I think the issue boils down to understanding what would be the solution at the XML schema (XSD) level. The first approach is to have each copybook map to a different namespace (I have omitted the COBOL annotations for clarity):
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://coxb.test.legstar.com/version1" elementFormDefault="qualified"
targetNamespace="http://coxb.test.legstar.com/version1">
<complexType name="MessageVersion1">
<sequence>
<element name="someString">
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
<element name="messageVersion1" type="tns:MessageVersion1"></element>
</schema>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://coxb.test.legstar.com/version2" elementFormDefault="qualified"
targetNamespace="http://coxb.test.legstar.com/version2">
<complexType name="MessageVersion2">
<sequence>
<element name="someString">
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
<element name="someString1">
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
<element name="messageVersion2" type="tns:MessageVersion2"></element>
</schema>
This of course is not satisfactory because JAXB will produce a completely different set of objects for each schema.
This is sample code that tests the JAXB objects generated out of such schemas:
import com.legstar.coxb.host.HostData;
import com.legstar.test.coxb.version1.MessageVersion1;
import com.legstar.test.coxb.version1.bind.MessageVersion1Transformers;
import junit.framework.TestCase;
public class Version1Test extends TestCase {
public void testVersion1() throws Exception {
MessageVersion1 msg = new MessageVersion1();
msg.setSomeString("foo");
MessageVersion1Transformers tf = new MessageVersion1Transformers();
byte[] hostData = tf.toHost(msg);
assertEquals("86969640404040404040", HostData.toHexString(hostData));
}
}
import com.legstar.coxb.host.HostData;
import com.legstar.test.coxb.version2.MessageVersion2;
import com.legstar.test.coxb.version2.bind.MessageVersion2Transformers;
import junit.framework.TestCase;
public class Version2Test extends TestCase {
public void testVersion2() throws Exception {
MessageVersion2 msg = new MessageVersion2();
msg.setSomeString("foo");
msg.setSomeString1("bar");
MessageVersion2Transformers tf = new MessageVersion2Transformers();
byte[] hostData = tf.toHost(msg);
assertEquals("8696964040404040404082819940404040404040", HostData.toHexString(hostData));
}
}
It is obvious that the version change is not transparent from a consumer code standpoint. Packages and Class names are different.
The second approach is something like this (same namespace, different schemaLocation):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="version1.xsd"
xmlns:tns="http://coxb.test.legstar.com/unversioned"
elementFormDefault="qualified"
targetNamespace="http://coxb.test.legstar.com/unversioned">
<complexType name="MessageVersion1">
<sequence>
<element name="someString">
<annotation>
<appinfo>
<cb:cobolElement cobolName="SOME-STRING" levelNumber="5" picture="X(10)" srceLine="2" type="ALPHANUMERIC_ITEM"/>
</appinfo>
</annotation>
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
<element name="messageVersion1" type="tns:MessageVersion1">
<annotation>
<appinfo>
<cb:cobolElement cobolName="MESSAGE-VERSION-1" levelNumber="1" srceLine="1" type="GROUP_ITEM"/>
</appinfo>
</annotation>
</element>
</schema>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="version2.xsd"
xmlns:tns="http://coxb.test.legstar.com/unversioned"
elementFormDefault="qualified"
targetNamespace="http://coxb.test.legstar.com/unversioned">
<complexType name="MessageVersion2">
<sequence>
<element name="someString">
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
<element name="someString1">
<simpleType>
<restriction base="string">
<maxLength value="10"/>
</restriction>
</simpleType>
</element>
</sequence>
</complexType>
<element name="messageVersion2" type="tns:MessageVersion2"></element>
</schema>
Again, this shows the impact on the code:
import com.legstar.coxb.host.HostData;
import com.legstar.test.coxb.unversioned.MessageVersion1;
import com.legstar.test.coxb.unversioned.bind.MessageVersion1Transformers;
import junit.framework.TestCase;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
public void testVersion1() throws Exception {
MessageVersion1 msg = new MessageVersion1();
msg.setSomeString("foo");
MessageVersion1Transformers tf = new MessageVersion1Transformers();
byte[] hostData = tf.toHost(msg);
assertEquals("86969640404040404040", HostData.toHexString(hostData));
}
}
import com.legstar.coxb.host.HostData;
import com.legstar.test.coxb.unversioned.MessageVersion2;
import com.legstar.test.coxb.unversioned.bind.MessageVersion2Transformers;
import junit.framework.TestCase;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
public void testVersion2() throws Exception {
MessageVersion2 msg = new MessageVersion2();
msg.setSomeString("foo");
msg.setSomeString1("bar");
MessageVersion2Transformers tf = new MessageVersion2Transformers();
byte[] hostData = tf.toHost(msg);
assertEquals("8696964040404040404082819940404040404040", HostData.toHexString(hostData));
}
}
This is slightly better because the Package names are identical this time. The class names are still different though. You can see that this primarily stems from the fact that you decided to rename the upper level COBOL item from MESSAGE-VERSION-1 to MESSAGE-VERSION-2.
Have you kept the same MESSAGE-VERSION name, the code would have been very similar.
Now, LegStar does not help in any way to generate the second form of XML schema. For now, this has to be done manually. Furthermore, the LegStar Eclipse plugins do not behave well when you use several XML schemas in the same Java project.
Hope this helps.
Fady