1 /* 2 * Copyright (c) 1997, 2013, 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 com.sun.xml.internal.bind.v2.util.XmlFactory; 40 import org.w3c.dom.ls.LSInput; 41 import org.w3c.dom.ls.LSResourceResolver; 42 import org.xml.sax.EntityResolver; 43 import org.xml.sax.InputSource; 44 import org.xml.sax.SAXException; 45 46 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; 47 48 /** 49 * Checks XML Schema XML representation constraints and 50 * schema component constraints by using JAXP 1.3 validation framework. 51 * <p/> 52 * 53 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 54 * @author Ryan Shoemaker (ryan.shoemaker@sun.com) 55 */ 56 public class SchemaConstraintChecker { 57 58 /** 59 * @param schemas Schema files to be checked. 60 * @param errorHandler detected errors will be reported to this handler. 61 * @return true if there was no error, false if there were errors. 62 */ 63 public static boolean check(InputSource[] schemas, 64 ErrorReceiver errorHandler, 65 final EntityResolver entityResolver, 66 boolean disableXmlSecurity) { 67 68 ErrorReceiverFilter errorFilter = new ErrorReceiverFilter(errorHandler); 69 boolean hadErrors = false; 70 71 SchemaFactory sf = XmlFactory.createSchemaFactory(W3C_XML_SCHEMA_NS_URI, disableXmlSecurity); 72 XmlFactory.allowExternalAccess(sf, "all", disableXmlSecurity); 73 sf.setErrorHandler(errorFilter); 74 if( entityResolver != null ) { 75 sf.setResourceResolver(new LSResourceResolver() { 76 public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) { 77 try { 78 // XSOM passes the namespace URI to the publicID parameter. 79 // we do the same here . 80 InputSource is = entityResolver.resolveEntity(namespaceURI, systemId); 81 if(is==null) return null; 82 return new LSInputSAXWrapper(is); 83 } catch (SAXException e) { 84 // TODO: is this sufficient? 85 return null; 86 } catch (IOException e) { 87 // TODO: is this sufficient? 88 return null; 89 } 90 } 91 }); 92 } 93 94 try { 95 XmlFactory.allowExternalDTDAccess(sf, "all", disableXmlSecurity); 96 sf.newSchema(getSchemaSource(schemas, entityResolver)); 97 } catch (SAXException e) { 98 // TODO: we haven't thrown exceptions from here before. should we just trap them and return false? 99 hadErrors = true; 100 } catch( OutOfMemoryError e) { 101 errorHandler.warning(null,Messages.format(Messages.WARN_UNABLE_TO_CHECK_CORRECTNESS)); 102 } 103 104 return !(hadErrors || errorFilter.hadError()); 105 } 106 107 /** 108 * convert an array of {@link InputSource InputSource} into an 109 * array of {@link Source Source} 110 * 111 * @param schemas array of {@link InputSource InputSource} 112 * @return array of {@link Source Source} 113 */ 114 private static Source[] getSchemaSource(InputSource[] schemas, EntityResolver entityResolver) throws SAXException { 115 SAXSource[] sources = new SAXSource[schemas.length]; 116 for (int i = 0; i < schemas.length; i++) { 117 sources[i] = new SAXSource(schemas[i]); 118 // sources[i].getXMLReader().setEntityResolver(entityResolver); 119 } 120 return sources; 121 } 122 123 // quick test 124 public static void main(String[] args) throws IOException { 125 InputSource[] sources = new InputSource[args.length]; 126 for (int i = 0; i < args.length; i++) 127 sources[i] = new InputSource(new File(args[i]).toURL().toExternalForm()); 128 129 check(sources, new ConsoleErrorReporter(), null, true); 130 } 131 }