src/share/jaxws_classes/com/sun/tools/internal/xjc/api/impl/s2j/SchemaCompilerImpl.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.tools.internal.xjc.api.impl.s2j;
ohair@286 27
ohair@286 28 import java.io.IOException;
ohair@286 29 import java.net.MalformedURLException;
ohair@286 30 import java.net.URI;
ohair@286 31 import java.net.URISyntaxException;
ohair@286 32 import java.net.URL;
ohair@286 33
ohair@286 34 import javax.xml.XMLConstants;
ohair@286 35 import javax.xml.stream.XMLStreamException;
ohair@286 36 import javax.xml.stream.XMLStreamReader;
ohair@286 37 import javax.xml.validation.SchemaFactory;
ohair@286 38
ohair@286 39 import com.sun.codemodel.internal.JCodeModel;
ohair@286 40 import com.sun.istack.internal.NotNull;
ohair@286 41 import com.sun.istack.internal.SAXParseException2;
ohair@286 42 import com.sun.tools.internal.xjc.ErrorReceiver;
ohair@286 43 import com.sun.tools.internal.xjc.ModelLoader;
ohair@286 44 import com.sun.tools.internal.xjc.Options;
ohair@286 45 import com.sun.tools.internal.xjc.api.ClassNameAllocator;
ohair@286 46 import com.sun.tools.internal.xjc.api.ErrorListener;
ohair@286 47 import com.sun.tools.internal.xjc.api.SchemaCompiler;
ohair@286 48 import com.sun.tools.internal.xjc.api.SpecVersion;
ohair@286 49 import com.sun.tools.internal.xjc.model.Model;
ohair@286 50 import com.sun.tools.internal.xjc.outline.Outline;
ohair@286 51 import com.sun.tools.internal.xjc.reader.internalizer.DOMForest;
ohair@286 52 import com.sun.tools.internal.xjc.reader.internalizer.SCDBasedBindingSet;
ohair@286 53 import com.sun.tools.internal.xjc.reader.xmlschema.parser.LSInputSAXWrapper;
ohair@286 54 import com.sun.tools.internal.xjc.reader.xmlschema.parser.XMLSchemaInternalizationLogic;
ohair@286 55 import com.sun.xml.internal.bind.unmarshaller.DOMScanner;
alanb@368 56 import com.sun.xml.internal.bind.v2.util.XmlFactory;
ohair@286 57 import com.sun.xml.internal.xsom.XSSchemaSet;
ohair@286 58
ohair@286 59 import org.w3c.dom.Element;
ohair@286 60 import org.w3c.dom.ls.LSInput;
ohair@286 61 import org.w3c.dom.ls.LSResourceResolver;
ohair@286 62 import org.xml.sax.ContentHandler;
ohair@286 63 import org.xml.sax.EntityResolver;
ohair@286 64 import org.xml.sax.InputSource;
ohair@286 65 import org.xml.sax.SAXException;
ohair@286 66 import org.xml.sax.SAXParseException;
ohair@286 67 import org.xml.sax.helpers.LocatorImpl;
ohair@286 68
ohair@286 69 /**
ohair@286 70 * {@link SchemaCompiler} implementation.
ohair@286 71 *
ohair@286 72 * This class builds a {@link DOMForest} until the {@link #bind()} method,
ohair@286 73 * then this method does the rest of the hard work.
ohair@286 74 *
ohair@286 75 * @see ModelLoader
ohair@286 76 *
ohair@286 77 * @author
ohair@286 78 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
ohair@286 79 */
ohair@286 80 public final class SchemaCompilerImpl extends ErrorReceiver implements SchemaCompiler {
ohair@286 81
ohair@286 82 /**
ohair@286 83 * User-specified error receiver.
ohair@286 84 * This field can be null, in which case errors need to be discarded.
ohair@286 85 */
ohair@286 86 private ErrorListener errorListener;
ohair@286 87
ohair@286 88 protected final Options opts = new Options();
ohair@286 89
ohair@286 90 protected @NotNull DOMForest forest;
ohair@286 91
ohair@286 92 /**
ohair@286 93 * Set to true once an error is found.
ohair@286 94 */
ohair@286 95 private boolean hadError;
ohair@286 96
ohair@286 97 public SchemaCompilerImpl() {
ohair@286 98 opts.compatibilityMode = Options.EXTENSION;
ohair@286 99 resetSchema();
ohair@286 100
ohair@286 101 if(System.getProperty("xjc-api.test")!=null) {
ohair@286 102 opts.debugMode = true;
ohair@286 103 opts.verbose = true;
ohair@286 104 }
ohair@286 105 }
ohair@286 106
ohair@286 107 @NotNull
ohair@286 108 public Options getOptions() {
ohair@286 109 return opts;
ohair@286 110 }
ohair@286 111
ohair@286 112 public ContentHandler getParserHandler( String systemId ) {
ohair@286 113 return forest.getParserHandler(systemId,true);
ohair@286 114 }
ohair@286 115
ohair@286 116 public void parseSchema( String systemId, Element element ) {
ohair@286 117 checkAbsoluteness(systemId);
ohair@286 118 try {
ohair@286 119 DOMScanner scanner = new DOMScanner();
ohair@286 120
ohair@286 121 // use a locator that sets the system ID correctly
ohair@286 122 // so that we can resolve relative URLs in most of the case.
ohair@286 123 // it still doesn't handle xml:base and XInclude and all those things
ohair@286 124 // correctly. There's just no way to make all those things work with DOM!
ohair@286 125 LocatorImpl loc = new LocatorImpl();
ohair@286 126 loc.setSystemId(systemId);
ohair@286 127 scanner.setLocator(loc);
ohair@286 128
ohair@286 129 scanner.setContentHandler(getParserHandler(systemId));
ohair@286 130 scanner.scan(element);
ohair@286 131 } catch (SAXException e) {
ohair@286 132 // since parsing DOM shouldn't cause a SAX exception
ohair@286 133 // and our handler will never throw it, it's not clear
ohair@286 134 // if this will ever happen.
ohair@286 135 fatalError(new SAXParseException2(
ohair@286 136 e.getMessage(), null, systemId,-1,-1, e));
ohair@286 137 }
ohair@286 138 }
ohair@286 139
ohair@286 140 public void parseSchema(InputSource source) {
ohair@286 141 checkAbsoluteness(source.getSystemId());
ohair@286 142 try {
ohair@286 143 forest.parse(source,true);
ohair@286 144 } catch (SAXException e) {
ohair@286 145 // parsers are required to report an error to ErrorHandler,
ohair@286 146 // so we should never see this error.
ohair@286 147 e.printStackTrace();
ohair@286 148 }
ohair@286 149 }
ohair@286 150
ohair@286 151 public void setTargetVersion(SpecVersion version) {
ohair@286 152 if(version==null)
ohair@286 153 version = SpecVersion.LATEST;
ohair@286 154 opts.target = version;
ohair@286 155 }
ohair@286 156
ohair@286 157 public void parseSchema(String systemId, XMLStreamReader reader) throws XMLStreamException {
ohair@286 158 checkAbsoluteness(systemId);
ohair@286 159 forest.parse(systemId,reader,true);
ohair@286 160 }
ohair@286 161
ohair@286 162 /**
ohair@286 163 * Checks if the system ID is absolute.
ohair@286 164 */
ohair@286 165 @SuppressWarnings("ResultOfObjectAllocationIgnored")
ohair@286 166 private void checkAbsoluteness(String systemId) {
ohair@286 167 // we need to be able to handle system IDs like "urn:foo", which java.net.URL can't process,
ohair@286 168 // but OTOH we also need to be able to process system IDs like "file://a b c/def.xsd",
ohair@286 169 // which java.net.URI can't process. So for now, let's fail only if both of them fail.
ohair@286 170 // eventually we need a proper URI class that works for us.
ohair@286 171 try {
ohair@286 172 new URL(systemId);
alanb@368 173 } catch( MalformedURLException mue) {
ohair@286 174 try {
ohair@286 175 new URI(systemId);
ohair@286 176 } catch (URISyntaxException e ) {
ohair@286 177 throw new IllegalArgumentException("system ID '"+systemId+"' isn't absolute",e);
ohair@286 178 }
ohair@286 179 }
ohair@286 180 }
ohair@286 181
ohair@286 182 public void setEntityResolver(EntityResolver entityResolver) {
ohair@286 183 forest.setEntityResolver(entityResolver);
ohair@286 184 opts.entityResolver = entityResolver;
ohair@286 185 }
ohair@286 186
ohair@286 187 public void setDefaultPackageName(String packageName) {
ohair@286 188 opts.defaultPackage2 = packageName;
ohair@286 189 }
ohair@286 190
ohair@286 191 public void forcePackageName(String packageName) {
ohair@286 192 opts.defaultPackage = packageName;
ohair@286 193 }
ohair@286 194
ohair@286 195 public void setClassNameAllocator(ClassNameAllocator allocator) {
ohair@286 196 opts.classNameAllocator = allocator;
ohair@286 197 }
ohair@286 198
ohair@286 199 public void resetSchema() {
alanb@368 200 forest = new DOMForest(new XMLSchemaInternalizationLogic(), opts);
ohair@286 201 forest.setErrorHandler(this);
ohair@286 202 forest.setEntityResolver(opts.entityResolver);
ohair@286 203 }
ohair@286 204
ohair@286 205 public JAXBModelImpl bind() {
ohair@286 206 // this has been problematic. turn it off.
ohair@286 207 // if(!forest.checkSchemaCorrectness(this))
ohair@286 208 // return null;
ohair@286 209
ohair@286 210 // parse all the binding files given via XJC -b options.
ohair@286 211 // this also takes care of the binding files given in the -episode option.
ohair@286 212 for (InputSource is : opts.getBindFiles())
ohair@286 213 parseSchema(is);
ohair@286 214
ohair@286 215 // internalization
ohair@286 216 SCDBasedBindingSet scdBasedBindingSet = forest.transform(opts.isExtensionMode());
ohair@286 217
ohair@286 218 if (!NO_CORRECTNESS_CHECK) {
ohair@286 219 // correctness check
alanb@368 220 SchemaFactory sf = XmlFactory.createSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI, opts.disableXmlSecurity);
ohair@286 221
ohair@286 222 // fix for https://jaxb.dev.java.net/issues/show_bug.cgi?id=795
ohair@286 223 // taken from SchemaConstraintChecker, TODO XXX FIXME UGLY
ohair@286 224 if (opts.entityResolver != null) {
ohair@286 225 sf.setResourceResolver(new LSResourceResolver() {
ohair@286 226 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
ohair@286 227 try {
ohair@286 228 // XSOM passes the namespace URI to the publicID parameter.
ohair@286 229 // we do the same here .
ohair@286 230 InputSource is = opts.entityResolver.resolveEntity(namespaceURI, systemId);
ohair@286 231 if (is == null) return null;
ohair@286 232 return new LSInputSAXWrapper(is);
ohair@286 233 } catch (SAXException e) {
ohair@286 234 // TODO: is this sufficient?
ohair@286 235 return null;
ohair@286 236 } catch (IOException e) {
ohair@286 237 // TODO: is this sufficient?
ohair@286 238 return null;
ohair@286 239 }
ohair@286 240 }
ohair@286 241 });
ohair@286 242 }
ohair@286 243
ohair@286 244 sf.setErrorHandler(new DowngradingErrorHandler(this));
ohair@286 245 forest.weakSchemaCorrectnessCheck(sf);
ohair@286 246 if (hadError)
ohair@286 247 return null; // error in the correctness check. abort now
ohair@286 248 }
ohair@286 249
ohair@286 250 JCodeModel codeModel = new JCodeModel();
ohair@286 251
ohair@286 252 ModelLoader gl = new ModelLoader(opts,codeModel,this);
ohair@286 253 try {
ohair@286 254 XSSchemaSet result = gl.createXSOM(forest, scdBasedBindingSet);
ohair@286 255 if(result==null)
ohair@286 256 return null;
ohair@286 257
ohair@286 258 // we need info about each field, so we go ahead and generate the
ohair@286 259 // skeleton at this point.
ohair@286 260 // REVISIT: we should separate FieldRenderer and FieldAccessor
ohair@286 261 // so that accessors can be used before we build the code.
ohair@286 262 Model model = gl.annotateXMLSchema(result);
ohair@286 263 if(model==null) return null;
ohair@286 264
ohair@286 265 if(hadError) return null; // if we have any error by now, abort
ohair@286 266
ohair@286 267 model.setPackageLevelAnnotations(opts.packageLevelAnnotations);
ohair@286 268
ohair@286 269 Outline context = model.generateCode(opts,this);
ohair@286 270 if(context==null) return null;
ohair@286 271
ohair@286 272 if(hadError) return null;
ohair@286 273
ohair@286 274 return new JAXBModelImpl(context);
ohair@286 275 } catch( SAXException e ) {
ohair@286 276 // since XSOM uses our parser that scans DOM,
ohair@286 277 // no parser error is possible.
ohair@286 278 // all the other errors will be directed to ErrorReceiver
ohair@286 279 // before it's thrown, so when the exception is thrown
ohair@286 280 // the error should have already been reported.
ohair@286 281
ohair@286 282 // thus ignore.
ohair@286 283 return null;
ohair@286 284 }
ohair@286 285 }
ohair@286 286
ohair@286 287 public void setErrorListener(ErrorListener errorListener) {
ohair@286 288 this.errorListener = errorListener;
ohair@286 289 }
ohair@286 290
ohair@286 291 public void info(SAXParseException exception) {
ohair@286 292 if(errorListener!=null)
ohair@286 293 errorListener.info(exception);
ohair@286 294 }
ohair@286 295 public void warning(SAXParseException exception) {
ohair@286 296 if(errorListener!=null)
ohair@286 297 errorListener.warning(exception);
ohair@286 298 }
ohair@286 299 public void error(SAXParseException exception) {
ohair@286 300 hadError = true;
ohair@286 301 if(errorListener!=null)
ohair@286 302 errorListener.error(exception);
ohair@286 303 }
ohair@286 304 public void fatalError(SAXParseException exception) {
ohair@286 305 hadError = true;
ohair@286 306 if(errorListener!=null)
ohair@286 307 errorListener.fatalError(exception);
ohair@286 308 }
ohair@286 309
ohair@286 310 /**
ohair@286 311 * We use JAXP 1.3 to do a schema correctness check, but we know
ohair@286 312 * it doesn't always work. So in case some people hit the problem,
ohair@286 313 * this switch is here so that they can turn it off as a workaround.
ohair@286 314 */
ohair@286 315 private static boolean NO_CORRECTNESS_CHECK = false;
ohair@286 316
ohair@286 317 static {
ohair@286 318 try {
ohair@286 319 NO_CORRECTNESS_CHECK = Boolean.getBoolean(SchemaCompilerImpl.class.getName()+".noCorrectnessCheck");
ohair@286 320 } catch( Throwable t) {
ohair@286 321 // ignore
ohair@286 322 }
ohair@286 323 }
ohair@286 324 }

mercurial