1 /* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.internal.xjc.reader.xmlschema.parser; 27 28 import java.io.File; 29 import java.io.IOException; 30 31 import javax.xml.transform.Source; 32 import javax.xml.transform.sax.SAXSource; 33 import javax.xml.validation.SchemaFactory; 34 35 import com.sun.tools.internal.xjc.ConsoleErrorReporter; 36 import com.sun.tools.internal.xjc.ErrorReceiver; 37 import com.sun.tools.internal.xjc.util.ErrorReceiverFilter; 38 39 import org.w3c.dom.ls.LSInput; 40 import org.w3c.dom.ls.LSResourceResolver; 41 import org.xml.sax.EntityResolver; 42 import org.xml.sax.InputSource; 43 import org.xml.sax.SAXException; 44 45 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; 46 47 /** 48 * Checks XML Schema XML representation constraints and 49 * schema component constraints by using JAXP 1.3 validation framework. 50 * <p/> 51 * 52 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 53 * @author Ryan Shoemaker (ryan.shoemaker@sun.com) 54 */ 55 public class SchemaConstraintChecker { 56 57 /** 58 * @param schemas Schema files to be checked. 59 * @param errorHandler detected errors will be reported to this handler. 60 * @return true if there was no error, false if there were errors. 61 */ 62 public static boolean check(InputSource[] schemas, 63 ErrorReceiver errorHandler, final EntityResolver entityResolver) { 64 65 ErrorReceiverFilter errorFilter = new ErrorReceiverFilter(errorHandler); 66 boolean hadErrors = false; 67 68 SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); 69 sf.setErrorHandler(errorFilter); 70 if( entityResolver != null ) { 71 sf.setResourceResolver(new LSResourceResolver() { 72 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { 73 try { 74 // XSOM passes the namespace URI to the publicID parameter. 75 // we do the same here . 76 InputSource is = entityResolver.resolveEntity(namespaceURI, systemId); 77 if(is==null) return null; 78 return new LSInputSAXWrapper(is); 79 } catch (SAXException e) { 80 // TODO: is this sufficient? 81 return null; 82 } catch (IOException e) { 83 // TODO: is this sufficient? 84 return null; 85 } 86 } 87 }); 88 } 89 90 try { 91 sf.newSchema(getSchemaSource(schemas, entityResolver)); 92 } catch (SAXException e) { 93 // TODO: we haven't thrown exceptions from here before. should we just trap them and return false? 94 hadErrors = true; 95 } catch( OutOfMemoryError e) { 96 errorHandler.warning(null,Messages.format(Messages.WARN_UNABLE_TO_CHECK_CORRECTNESS)); 97 } 98 99 return !(hadErrors || errorFilter.hadError()); 100 } 101 102 /** 103 * convert an array of {@link InputSource InputSource} into an 104 * array of {@link Source Source} 105 * 106 * @param schemas array of {@link InputSource InputSource} 107 * @return array of {@link Source Source} 108 */ 109 private static Source[] getSchemaSource(InputSource[] schemas, EntityResolver entityResolver) throws SAXException { 110 SAXSource[] sources = new SAXSource[schemas.length]; 111 for (int i = 0; i < schemas.length; i++) { 112 sources[i] = new SAXSource(schemas[i]); 113 // sources[i].getXMLReader().setEntityResolver(entityResolver); 114 } 115 return sources; 116 } 117 118 // quick test 119 public static void main(String[] args) throws IOException { 120 InputSource[] sources = new InputSource[args.length]; 121 for (int i = 0; i < args.length; i++) 122 sources[i] = new InputSource(new File(args[i]).toURL().toExternalForm()); 123 124 check(sources, new ConsoleErrorReporter(), null); 125 } 126 }