users@jaxb.java.net

XJC API for runtime code generation

From: Mark Proctor <mproctor_at_codehaus.org>
Date: Sat, 12 Jul 2008 03:13:48 +0100

I'm trying to get XJC to generate the src code for an XSD model at
runtime using the XJC api, using just input streams as we don't want
disk access. This is to facilite the data loading of XSD based models
into Drools at runtime. We will compile the src at runtime using an
embedded compiler and add it to the Drools classloader. I've already
done something similar for a Smooks data loadaer
http://blog.athico.com/2008/07/drools-smooks-data-loader.html. I've
looked over the maven plugin for XJC, changing it from a File based
utility to InputStreams, although now stuck. I've included the test code
below, along with the error and the xsd. If anyone can help, or point me
to some code that already does this, would be very much appreciated.

Thanks

Mark

--------The Test-------------
test1() throws Exception {
    Options xjcOpts = new Options();
    xjcOpts.setSchemaLanguage( Language.XMLSCHEMA );
    InputStream stream = getClass().getResourceAsStream( "test.xsd" );
    assertNotNull( stream ); InputSource source = new InputSource( new
InputStreamReader( stream ) );

    source.setSystemId( ".xsd" );
    xjcOpts.addGrammar( source );
    ErrorReceiver errorReceiver = new JaxbErrorReceiver4Drools();
    Model model = ModelLoader.load( xjcOpts, new JCodeModel(),
errorReceiver);
    final Outline outline = model.generateCode(xjcOpts, errorReceiver);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    model.codeModel.build( xjcOpts.createCodeWriter( new
SingleStreamCodeWriter( baos ) ) );
    String str = new String( baos.toByteArray() );
    System.out.println( str );
}

public class JaxbErrorReceiver4Drools extends ErrorReceiver {
    public String stage = "processing";

    public void warning(SAXParseException e) {
        e.printStackTrace();
    }

    public void error(SAXParseException e) {
        e.printStackTrace();
    }

    public void fatalError(SAXParseException e) {
        e.printStackTrace();
    }

    public void info(SAXParseException e) {
        e.printStackTrace();
    }
}

-------------The Error----------------
java.io.IOException: Stream closed
at
com.sun.xml.xsom.impl.parser.NGCCRuntimeEx.parseEntity(NGCCRuntimeEx.java:305)
at com.sun.xml.xsom.impl.parser.ParserContext.parse(ParserContext.java:88)
   at com.sun.xml.xsom.parser.XSOMParser.parse(XSOMParser.java:147)
at com.sun.tools.xjc.ModelLoader.createXSOMSpeculative(ModelLoader.java:496)
   at com.sun.tools.xjc.ModelLoader.loadXMLSchema(ModelLoader.java:366)
   at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:167)
   at com.sun.tools.xjc.ModelLoader.load(ModelLoader.java:113)
at org.drools.dataloaders.jaxb.DroolsJaxbTest.test1(DroolsJaxbTest.java:36)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

-----------The test.xsd file-----------
schema xmlns = "http://www.w3.org/2001/XMLSchema";
       xmlns:exp="http://www.oracle.com/sample3/";
       targetNamespace="http://www.oracle.com/sample3/";
       elementFormDefault="qualified">

  <complexType name="Address">
     <sequence>
        <element name="name" type="string"/>
        <element name="doorNumber" type="short"/>
        <element name="street" type="string"/>
        <element name="city" type="string"/>
     </sequence>
  </complexType>

 <complexType name="USAddress">
   <complexContent>
    <extension base="exp:Address">
      <sequence>
         <element name="state" type="string"/>
         <element name="zip" type="integer"/>
         <element name="country" type="string"/>
      </sequence>
    </extension>
   </complexContent>
 </complexType>

 <element name="myAddress" type="exp:USAddress"/>

</schema>