As mentioned in @ df778899, if you looked at the source code below, nothing can be done about it
CElementPropertyInfo p; if(b.isRepeated || b.elements.size()>1) { // collection StringBuilder name = new StringBuilder(); for( Element e : b.elements ) { if(name.length()>0) name.append("Or"); name.append(owner.model.getNameConverter().toPropertyName(e.name)); } p = new CElementPropertyInfo(name.toString(), REPEATED_ELEMENT, ID.NONE, null, null,null/*TODO*/, locator, !b.isOptional ); for( Element e : b.elements ) { CClassInfo child = owner.getOrCreateElement(e.name).getClassInfo(); assert child!=null; // we are requiring them to be classes. p.getTypes().add(new CTypeRef(child,new QName("",e.name),null,false,null)); }
The CElementPropertyInfo
object takes a name, and the only way to fix it is to use a toolkit. So I created a maven project
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.tarunlalwani</groupId> <artifactId>jxc-customizer</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.22.0-GA</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/libs </outputDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <archive> <manifestEntries> <Premain-Class>com.xjc.javaagent.SimpleAgent</Premain-Class> <Boot-Class-Path>libs/javassist-3.22.0-GA.jar</Boot-Class-Path> <Class-Path>libs/javassist-3.22.0-GA.jar</Class-Path> </manifestEntries> <manifest> <classpathPrefix>libs/</classpathPrefix> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>
jxccustomizer / SRC / main / Java / COM / XJC / javaagent / SimpleAgent.java
package com.xjc.javaagent; import java.lang.instrument.Instrumentation; public class SimpleAgent { public static void premain(String agentArgs, Instrumentation instrumentation){ System.out.println("Starting Agent"); SimpleClassFileTransformer transformer = new SimpleClassFileTransformer(); instrumentation.addTransformer(transformer); } }
jxccustomizer / SRC / main / Java / COM / XJC / javaagent / SimpleClassFileTransformer.java
package com.xjc.javaagent; import javassist.*; import java.io.ByteArrayInputStream; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; public class SimpleClassFileTransformer implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { byte[] byteCode = classfileBuffer; if (className.endsWith("/CPropertyInfo")) { System.out.println("Loading class - " + className); try { ClassPool classPool = ClassPool.getDefault(); CtClass ctClass = classPool.makeClass( new ByteArrayInputStream(classfileBuffer)); CtConstructor[] constructors = ctClass.getConstructors(); for (CtConstructor c : constructors) { c.insertBefore("{ String propFile = System.getProperty(\"XJC_REMAP\");\n" + " if (propFile != null)\n" + " {\n" + " System.out.println(\"External remap file provided\");\n" + " java.util.Properties props = new java.util.Properties();\n" + " try {\n" + " props.load(new java.io.FileInputStream(propFile));\n" + " java.util.Enumeration enums = props.propertyNames();\n" + " while (enums.hasMoreElements()) {\n" + " String key = (String)enums.nextElement();\n" + " String value = props.getProperty(key);\n" + " try {\n" + " System.out.println(\"Checking if \" + name + \" matches \" + key);\n" + " java.util.regex.Pattern pat = java.util.regex.Pattern.compile(\"^\" + key +\"$\", java.util.regex.Pattern.CASE_INSENSITIVE);\n" + " if (pat.matcher(name).find())\n" + " {\n" + " System.out.println(\"Replacing \" + name + \" with \" + value);\n" + " name = value;\n" + " break;\n" + " }\n" + " } finally {\n" + " if (name == key) {\n" + " System.out.println(\"Replacing \" + name + \" with \" + value);\n" + " name = value;\n" + " }\n" + " break;\n" + " }\n" + " }\n" + " } catch (java.io.IOException e) {\n" + " e.printStackTrace();\n" + " }\n" + " }}"); } byteCode = ctClass.toBytecode(); ctClass.detach(); System.out.println("NO Exception occured"); } catch (Throwable e) { System.out.println("Exception occurred"); e.printStackTrace(); } } return byteCode; } }
The above class can load the properties file specified by -DXJC_REMAP=<filepath>
, which will have the format below
remap.properties
docPageOr.*=patentDocument
Now test the solution. First you need to create a jar
for the agent by running the command
mvn clean package
Next you need to create some dtd
testing
binding.xjb
<?xml version="1.0"?> <xml-java-binding-schema> <options package="org"/> <element name="us-patent-grant" type="class" root="true"></element> </xml-java-binding-schema>
testing.dtd
<?xml version="1.0" encoding="utf-8"?> <!ELEMENT us-patent-grant (doc-page+ | (us-bibliographic-data-grant , abstract* , drawings? , description , us-sequence-list-doc? , us-megatable-doc?,table-external-doc* , us-chemistry* , us-math* ,us-claim-statement , claims))>
Now, to use this to start the agent using xjc
$ export _JAVA_OPTIONS="-javaagent:/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/jaxb/jxccustomizer/target/jxc-customizer-1.0-SNAPSHOT.jar -DXJC_REMAP=/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/jaxb/remap.properties" $ xjc -b binding.xjb -dtd testing.dtd Picked up _JAVA_OPTIONS: -javaagent:/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/jaxb/jxccustomizer/target/jxc-customizer-1.0-SNAPSHOT.jar -DXJC_REMAP=/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/workshop/ub16/so/jaxb/remap.properties objc[33035]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/xjc (0x10ed964c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10eded4e0). One of the two will be used. Which one is undefined. Starting Agent Loading class 2 - com/sun/tools/internal/xjc/model/CPropertyInfo inside try Updating cons 1 Updating cons NO Exception occured parsing a schema... External remap file provided Checking if DocPageOrUsBibliographicDataGrantOrAbstractOrDrawingsOrDescriptionOrUsSequenceListDocOrUsMegatableDocOrTableExternalDocOrUsChemistryOrUsMathOrUsClaimStatementOrClaims matches docPageOr.* Replacing DocPageOrUsBibliographicDataGrantOrAbstractOrDrawingsOrDescriptionOrUsSequenceListDocOrUsMegatableDocOrTableExternalDocOrUsChemistryOrUsMathOrUsClaimStatementOrClaims with patentDocument compiling a schema... org/Abstract.java org/Claims.java org/Description.java org/DocPage.java org/Drawings.java org/ObjectFactory.java org/TableExternalDoc.java org/UsBibliographicDataGrant.java org/UsChemistry.java org/UsClaimStatement.java org/UsMath.java org/UsMegatableDoc.java org/UsPatentGrant.java org/UsSequenceListDoc.java
And now the contents of the generated file as desired

The git repo for the above code is available at the link below
https://github.com/tarunlalwani/xjc-java-agent-customization