1 /* 2 * Copyright (c) 1997, 2015, 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.xml.internal.xsom.impl.parser; 27 28 import com.sun.xml.internal.xsom.XSSchemaSet; 29 import com.sun.xml.internal.xsom.impl.ElementDecl; 30 import com.sun.xml.internal.xsom.impl.SchemaImpl; 31 import com.sun.xml.internal.xsom.impl.SchemaSetImpl; 32 import com.sun.xml.internal.xsom.parser.AnnotationParserFactory; 33 import com.sun.xml.internal.xsom.parser.XMLParser; 34 import com.sun.xml.internal.xsom.parser.XSOMParser; 35 import org.xml.sax.EntityResolver; 36 import org.xml.sax.ErrorHandler; 37 import org.xml.sax.InputSource; 38 import org.xml.sax.Locator; 39 import org.xml.sax.SAXException; 40 import org.xml.sax.SAXParseException; 41 42 import java.io.InputStream; 43 import java.util.HashMap; 44 import java.util.Iterator; 45 import java.util.Map; 46 import java.util.Vector; 47 48 /** 49 * Provides context information to be used by {@link NGCCRuntimeEx}s. 50 * 51 * <p> 52 * This class does the actual processing for {@link XSOMParser}, 53 * but to hide the details from the public API, this class in 54 * a different package. 55 * 56 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 57 */ 58 public class ParserContext { 59 60 /** SchemaSet to which a newly parsed schema is put in. */ 61 public final SchemaSetImpl schemaSet = new SchemaSetImpl(); 62 63 private final XSOMParser owner; 64 65 final XMLParser parser; 66 67 68 private final Vector<Patch> patchers = new Vector<Patch>(); 69 private final Vector<Patch> errorCheckers = new Vector<Patch>(); 70 71 /** 72 * Documents that are parsed already. Used to avoid cyclic inclusion/double 73 * inclusion of schemas. Set of {@link SchemaDocumentImpl}s. 74 * 75 * The actual data structure is map from {@link SchemaDocumentImpl} to itself, 76 * so that we can access the {@link SchemaDocumentImpl} itself. 77 */ 78 public final Map<SchemaDocumentImpl, SchemaDocumentImpl> parsedDocuments = new HashMap<SchemaDocumentImpl, SchemaDocumentImpl>(); 79 80 81 public ParserContext( XSOMParser owner, XMLParser parser ) { 82 this.owner = owner; 83 this.parser = parser; 84 85 try { 86 InputStream is = ParserContext.class.getResourceAsStream("datatypes.xsd"); 87 InputSource source = new InputSource(is); 88 source.setSystemId("datatypes.xsd"); 89 parse(source); 90 91 SchemaImpl xs = (SchemaImpl) 92 schemaSet.getSchema("http://www.w3.org/2001/XMLSchema"); 93 xs.addSimpleType(schemaSet.anySimpleType,true); 94 xs.addComplexType(schemaSet.anyType,true); 95 } catch( SAXException e ) { 96 // this must be a bug of XSOM 97 if(e.getException()!=null) 98 e.getException().printStackTrace(); 99 else 100 e.printStackTrace(); 101 throw new InternalError(); 102 } 103 } 104 105 public EntityResolver getEntityResolver() { 106 return owner.getEntityResolver(); 107 } 108 109 public AnnotationParserFactory getAnnotationParserFactory() { 110 return owner.getAnnotationParserFactory(); 111 } 112 113 /** 114 * Parses a new XML Schema document. 115 */ 116 public void parse( InputSource source ) throws SAXException { 117 newNGCCRuntime().parseEntity(source,false,null,null); 118 } 119 120 121 public XSSchemaSet getResult() throws SAXException { 122 // run all the patchers 123 for (Patch patcher : patchers) 124 patcher.run(); 125 patchers.clear(); 126 127 // build the element substitutability map 128 Iterator itr = schemaSet.iterateElementDecls(); 129 while(itr.hasNext()) 130 ((ElementDecl)itr.next()).updateSubstitutabilityMap(); 131 132 // run all the error checkers 133 for (Patch patcher : errorCheckers) 134 patcher.run(); 135 errorCheckers.clear(); 136 137 138 if(hadError) return null; 139 else return schemaSet; 140 } 141 142 public NGCCRuntimeEx newNGCCRuntime() { 143 return new NGCCRuntimeEx(this); 144 } 145 146 147 148 /** Once an error is detected, this flag is set to true. */ 149 private boolean hadError = false; 150 151 /** Turns on the error flag. */ 152 void setErrorFlag() { hadError=true; } 153 154 /** 155 * PatchManager implementation, which is accessible only from 156 * NGCCRuntimEx. 157 */ 158 final PatcherManager patcherManager = new PatcherManager() { 159 public void addPatcher( Patch patch ) { 160 patchers.add(patch); 161 } 162 public void addErrorChecker( Patch patch ) { 163 errorCheckers.add(patch); 164 } 165 public void reportError( String msg, Locator src ) throws SAXException { 166 // set a flag to true to avoid returning a corrupted object. 167 setErrorFlag(); 168 169 SAXParseException e = new SAXParseException(msg,src); 170 if(errorHandler==null) 171 throw e; 172 else 173 errorHandler.error(e); 174 } 175 }; 176 177 /** 178 * ErrorHandler proxy to turn on the hadError flag when an error 179 * is found. 180 */ 181 final ErrorHandler errorHandler = new ErrorHandler() { 182 private ErrorHandler getErrorHandler() { 183 if( owner.getErrorHandler()==null ) 184 return noopHandler; 185 else 186 return owner.getErrorHandler(); 187 } 188 189 public void warning(SAXParseException e) throws SAXException { 190 getErrorHandler().warning(e); 191 } 192 193 public void error(SAXParseException e) throws SAXException { 194 setErrorFlag(); 195 getErrorHandler().error(e); 196 } 197 198 public void fatalError(SAXParseException e) throws SAXException { 199 setErrorFlag(); 200 getErrorHandler().fatalError(e); 201 } 202 }; 203 204 /** 205 * {@link ErrorHandler} that does nothing. 206 */ 207 final ErrorHandler noopHandler = new ErrorHandler() { 208 public void warning(SAXParseException e) { 209 } 210 public void error(SAXParseException e) { 211 } 212 public void fatalError(SAXParseException e) { 213 setErrorFlag(); 214 } 215 }; 216 }