Repository: cxf-xjc-utils Updated Branches: refs/heads/master 44b959656 -> 2d065ea5a
Attempt to workaround JAXB-1026 via some byte bode manipulation. Kind of crappy. Project: http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/commit/2d065ea5 Tree: http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/tree/2d065ea5 Diff: http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/diff/2d065ea5 Branch: refs/heads/master Commit: 2d065ea5a489a7490b943310ef1f5fdaa5082629 Parents: 44b9596 Author: Daniel Kulp <[email protected]> Authored: Thu Jun 19 17:39:30 2014 -0400 Committer: Daniel Kulp <[email protected]> Committed: Thu Jun 19 17:39:30 2014 -0400 ---------------------------------------------------------------------- cxf-xjc-plugin/pom.xml | 5 + .../cxf/maven_plugin/AbstractXSDToJavaMojo.java | 2 + .../cxf/maven_plugin/XSDToJavaRunner.java | 173 ++++++++++++++++++- 3 files changed, 173 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/blob/2d065ea5/cxf-xjc-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/cxf-xjc-plugin/pom.xml b/cxf-xjc-plugin/pom.xml index 61732eb..f421281 100644 --- a/cxf-xjc-plugin/pom.xml +++ b/cxf-xjc-plugin/pom.xml @@ -106,6 +106,11 @@ <artifactId>xml-resolver</artifactId> <version>1.2</version> </dependency> + <dependency> + <groupId>org.javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.18.2-GA</version> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/blob/2d065ea5/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/AbstractXSDToJavaMojo.java ---------------------------------------------------------------------- diff --git a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/AbstractXSDToJavaMojo.java b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/AbstractXSDToJavaMojo.java index 1af0dff..782a8bb 100644 --- a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/AbstractXSDToJavaMojo.java +++ b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/AbstractXSDToJavaMojo.java @@ -26,6 +26,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.apache.maven.artifact.Artifact; @@ -279,6 +280,7 @@ public abstract class AbstractXSDToJavaMojo extends AbstractMojo { private int run(XsdOption option, String outputDir) throws Exception { if (!fork) { String[] args = getArguments(option, outputDir); + this.getLog().debug("Args: " + Arrays.asList(args)); XJCErrorListener listener = new XJCErrorListener(buildContext); int i = new XSDToJavaRunner(args, listener, new File(option.getXsd()), getClasspathElements()).run(); if (i != 0 && listener.getFirstError() != null) { http://git-wip-us.apache.org/repos/asf/cxf-xjc-utils/blob/2d065ea5/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java ---------------------------------------------------------------------- diff --git a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java index bd4724b..ef4e2a1 100644 --- a/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java +++ b/cxf-xjc-plugin/src/main/java/org/apache/cxf/maven_plugin/XSDToJavaRunner.java @@ -22,6 +22,8 @@ package org.apache.cxf.maven_plugin; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -29,30 +31,46 @@ import java.util.List; import javax.xml.bind.annotation.XmlElementRef; +import org.xml.sax.Attributes; import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.XMLFilterImpl; import com.sun.codemodel.CodeWriter; import com.sun.codemodel.JCodeModel; +import com.sun.istack.SAXParseException2; +import com.sun.tools.xjc.ErrorReceiver; import com.sun.tools.xjc.Language; -import com.sun.tools.xjc.ModelLoader; import com.sun.tools.xjc.Options; import com.sun.tools.xjc.api.SpecVersion; import com.sun.tools.xjc.model.Model; import com.sun.tools.xjc.outline.Outline; +import com.sun.tools.xjc.reader.internalizer.AbstractReferenceFinderImpl; +import com.sun.tools.xjc.reader.internalizer.DOMForest; +import com.sun.tools.xjc.reader.xmlschema.parser.XMLSchemaInternalizationLogic; import org.apache.xml.resolver.CatalogManager; import org.apache.xml.resolver.tools.CatalogResolver; import org.sonatype.plexus.build.incremental.BuildContext; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + /** * */ public class XSDToJavaRunner { + static Class<?> modelLoaderClass; + final String[] args; final List<String> cpList; final XJCErrorListener listener; final File xsdFile; + public XSDToJavaRunner(String[] args, XJCErrorListener listener, File file, List<String> cp) { this.args = args; @@ -74,10 +92,6 @@ public class XSDToJavaRunner { final CatalogResolver catResolver = new CatalogResolver(cm) { public InputSource resolveEntity(String publicId, String systemId) { String resolved = getResolvedEntity(publicId, systemId); - //System.out.println("Resolved: "); - //System.out.println(" : " + publicId); - //System.out.println(" : " + systemId); - //System.out.println(" -> " + resolved); if (resolved == null) { return null; } @@ -95,6 +109,7 @@ public class XSDToJavaRunner { InputStream iStream = url.openStream(); iSource.setByteStream(iStream); + //System.out.println("Resolved: " + publicId + " " + systemId + " " + url); return iSource; } catch (Exception e) { listener.warning(xsdFile, e); @@ -116,7 +131,7 @@ public class XSDToJavaRunner { } opt.setSchemaLanguage(Language.XMLSCHEMA); opt.parseArguments(args); - Model model = ModelLoader.load(opt, new JCodeModel(), listener); + Model model = loadModel(opt); if (model == null) { listener.message(xsdFile, "Failed to create model"); return -1; @@ -137,6 +152,147 @@ public class XSDToJavaRunner { } return 0; } + + + private synchronized Class<?> getModelLoaderClass() { + if (modelLoaderClass == null) { + try { + ClassPool pool = ClassPool.getDefault(); + CtClass cc = pool.get("com.sun.tools.xjc.ModelLoader"); + cc.setName("com.sun.tools.xjc.ModelLoader"); + for (CtMethod m : cc.getMethods()) { + if (m.getName().equals("buildDOMForest")) { + m.insertBefore("$1 = new " + CustomizedLogic.class.getName() + "();"); + } + } + modelLoaderClass = cc.toClass(); + } catch (Throwable t) { + try { + modelLoaderClass = Class.forName("com.sun.tools.xjc.ModelLoader"); + } catch (ClassNotFoundException e) { + //ignore + } + } + } + return modelLoaderClass; + } + + private Model loadModel(Options opt) { + try { + return (Model)getModelLoaderClass() + .getMethod("load", Options.class, JCodeModel.class, ErrorReceiver.class) + .invoke(null, opt, new JCodeModel(), listener); + } catch (Throwable e) { + return null; + } + } + + public static class CustomizedLogic extends XMLSchemaInternalizationLogic { + private static final class ReferenceFinder extends AbstractReferenceFinderImpl { + private Locator locator; + + ReferenceFinder(DOMForest parent) { + super(parent); + } + + @Override + public void setDocumentLocator(Locator l) { + super.setDocumentLocator(l); + locator = l; + } + + @Override + public void startElement(String namespaceURI, String localName, String qName, Attributes atts) + throws SAXException { + if (getContentHandler() != null) { + getContentHandler().startElement(namespaceURI, localName, qName, atts); + } + + String relativeRef = findExternalResource(namespaceURI, localName, atts); + if (relativeRef == null) { + return; // not found + } + try { + // absolutize URL. + String lsi = locator.getSystemId(); + String ref; + URI relRefURI = new URI(relativeRef); + if (relRefURI.isAbsolute()) { + ref = relativeRef; + } else { + if (lsi.startsWith("jar:")) { + int bangIdx = lsi.indexOf('!'); + if (bangIdx > 0) { + ref = lsi.substring(0, bangIdx + 1) + + new URI(lsi.substring(bangIdx + 1)).resolve(new URI(relativeRef)).toString(); + } else { + ref = relativeRef; + } + } else { + ref = new URI(lsi).resolve(new URI(relativeRef)).toString(); + } + } + + if (parent != null) { + ref = Options.normalizeSystemId(ref); + + if (parent.get(ref) != null) { + return; + } + + InputSource is = null; + + // allow entity resolver to find the actual byte stream. + if (parent.getEntityResolver() != null) { + is = parent.getEntityResolver().resolveEntity(null, ref); + } + if (is == null) { + is = new InputSource(ref); + } else { + ref = is.getSystemId(); + } + if (parent.get(ref) != null) { + is.getByteStream().close(); + return; + } + parent.parse(ref, is, false); + } + } catch (URISyntaxException e) { + String msg = e.getMessage(); + if (new File(relativeRef).exists()) { + msg = "Filename is not a URI " + ' ' + msg; + } + + SAXParseException spe = new SAXParseException2( + "Unable to parse " + relativeRef + ": " + msg, + locator, e); + + fatalError(spe); + throw spe; + } catch (IOException e) { + SAXParseException spe = new SAXParseException2( + "Unable to parse " + relativeRef + ": " + e.getMessage(), + locator, e); + + fatalError(spe); + throw spe; + } + } + + protected String findExternalResource(String nsURI, String localName, Attributes atts) { + if ("http://www.w3.org/2001/XMLSchema".equals(nsURI) + && ("import".equals(localName) || "include".equals(localName))) { + return atts.getValue("schemaLocation"); + } + return null; + } + } + + public XMLFilterImpl createExternalReferenceFinder(DOMForest parent) { + return new ReferenceFinder(parent); + } + } + private boolean checkXmlElementRef() { try { //check the version of JAXB-API that is actually being picked up @@ -147,12 +303,15 @@ public class XSDToJavaRunner { } return false; } + public static void main(String[] args) throws Exception { + List<String> cplist = new ArrayList<String>(); + BuildContext context = new XJCBuildContext(); XJCErrorListener listener = new XJCErrorListener(context); File outputFile = new File(args[args.length - 1]); - int i = new XSDToJavaRunner(args, listener, outputFile, new ArrayList<String>()).run(); + int i = new XSDToJavaRunner(args, listener, outputFile, cplist).run(); System.exit(i); }
