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