Friday, June 8, 2007

xmlbean: create .xsdconfig automatically from xsd file with customized package name

One task I had before is to create a xmlbean jar file from a set of very big xsd files, the resulting jar file is about 40MB, and also the package name of generated xmlbean classes need to be different from the default one, basically it needs to have version name:

original package name:
com.mycompany.account.address

modified package name (added v2):
com.mycompany.v2.account.address

There is only one entry xsd file, but it includes about hundreds of other xsd files, so it is almost impossible to create a .xsdconfig that will map the xsd name space to package name.

My goal is to create a repeatable and easy way to auto. generate the .xsdconfig with the mapping.

Step 1:
Use textpad or write a simple java program to search the keyword "targetNamespace=" for all xsd files, and save the output to a file named raw_namespace.txt

Step 2:
Create a java program that will read the raw_namespace.txt, then use xmlbean internal util to create package name and map that package name to new package name, then save the output to .xsdconfig

Step 2.1:
defined the mapping:
private final static HashMap nsToPackage = new HashMap();
static {
nsToPackage.put("http://service.mycompany.com", "com.mycompany.v2");
}

Step 2.2:

read the raw_namespace.txt and loop the line, then pass the value from "targetNamespace" to this function to get a new complete package name, the key here is to create a fake name space, then use the xmlbean util program NameUtil.getPackageFromNamespace to generate the package name from the fake name space:

private String getPackageName(String ns) {
String pkn = null;
Iterator it = nsToPackage.keySet().iterator();
while (it.hasNext()) {
String nsprefix = (String)it.next();
if (ns.startsWith(nsprefix)) {
StringBuffer sb = new StringBuffer();
sb.append(nsToPackage.get(nsprefix));
String nssuffix = ns.substring(nsprefix.length()+1);
String pname = NameUtil.getPackageFromNamespace(nssuffix);
sb.append(pname);
pkn = sb.toString();
break;
}
}
return pkn;
}


Step 2.3:
combine all the output from step 2.2 to .xsdconfig, which looks like this:
<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">
<xb:namespace uri="http://service.mycompany.com/account/address/">
<xb:package>com.mycompany.v2.account.address</xb:package>
</xb:namespace>
<xb:namespace uri="http://service.mycompany.com/common/getZipcode/">
<xb:package>com.mycompany.v2.common.getZipcode</xb:package>
</xb:namespace>
</xb:config>


The about steps can be simplify by hooking into ant API and then just do an ant build each time, but you get the point.

1 comment:

Anonymous said...

Well written article.