001: package com.sun.xml.xsom.impl.parser;
002:
003: import com.sun.xml.xsom.XSSchemaSet;
004: import com.sun.xml.xsom.impl.ElementDecl;
005: import com.sun.xml.xsom.impl.SchemaImpl;
006: import com.sun.xml.xsom.impl.SchemaSetImpl;
007: import com.sun.xml.xsom.parser.AnnotationParserFactory;
008: import com.sun.xml.xsom.parser.XMLParser;
009: import com.sun.xml.xsom.parser.XSOMParser;
010: import org.xml.sax.EntityResolver;
011: import org.xml.sax.ErrorHandler;
012: import org.xml.sax.InputSource;
013: import org.xml.sax.Locator;
014: import org.xml.sax.SAXException;
015: import org.xml.sax.SAXParseException;
016:
017: import java.util.HashMap;
018: import java.util.Iterator;
019: import java.util.Map;
020: import java.util.Vector;
021:
022: /**
023: * Provides context information to be used by {@link NGCCRuntimeEx}s.
024: *
025: * <p>
026: * This class does the actual processing for {@link XSOMParser},
027: * but to hide the details from the public API, this class in
028: * a different package.
029: *
030: * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
031: */
032: public class ParserContext {
033:
034: /** SchemaSet to which a newly parsed schema is put in. */
035: public final SchemaSetImpl schemaSet = new SchemaSetImpl();
036:
037: private final XSOMParser owner;
038:
039: final XMLParser parser;
040:
041: private final Vector<Patch> patchers = new Vector<Patch>();
042: private final Vector<Patch> errorCheckers = new Vector<Patch>();
043:
044: /**
045: * Documents that are parsed already. Used to avoid cyclic inclusion/double
046: * inclusion of schemas. Set of {@link SchemaDocumentImpl}s.
047: *
048: * The actual data structure is map from {@link SchemaDocumentImpl} to itself,
049: * so that we can access the {@link SchemaDocumentImpl} itself.
050: */
051: public final Map<SchemaDocumentImpl, SchemaDocumentImpl> parsedDocuments = new HashMap<SchemaDocumentImpl, SchemaDocumentImpl>();
052:
053: public ParserContext(XSOMParser owner, XMLParser parser) {
054: this .owner = owner;
055: this .parser = parser;
056:
057: try {
058: parse(new InputSource(ParserContext.class.getResource(
059: "datatypes.xsd").toExternalForm()));
060:
061: SchemaImpl xs = (SchemaImpl) schemaSet
062: .getSchema("http://www.w3.org/2001/XMLSchema");
063: xs.addSimpleType(schemaSet.anySimpleType, true);
064: xs.addComplexType(schemaSet.anyType, true);
065: } catch (SAXException e) {
066: // this must be a bug of XSOM
067: if (e.getException() != null)
068: e.getException().printStackTrace();
069: else
070: e.printStackTrace();
071: throw new InternalError();
072: }
073: }
074:
075: public EntityResolver getEntityResolver() {
076: return owner.getEntityResolver();
077: }
078:
079: public AnnotationParserFactory getAnnotationParserFactory() {
080: return owner.getAnnotationParserFactory();
081: }
082:
083: /**
084: * Parses a new XML Schema document.
085: */
086: public void parse(InputSource source) throws SAXException {
087: newNGCCRuntime().parseEntity(source, false, null, null);
088: }
089:
090: public XSSchemaSet getResult() throws SAXException {
091: // run all the patchers
092: for (Patch patcher : patchers)
093: patcher.run();
094: patchers.clear();
095:
096: // build the element substitutability map
097: Iterator itr = schemaSet.iterateElementDecls();
098: while (itr.hasNext())
099: ((ElementDecl) itr.next()).updateSubstitutabilityMap();
100:
101: // run all the error checkers
102: for (Patch patcher : errorCheckers)
103: patcher.run();
104: errorCheckers.clear();
105:
106: if (hadError)
107: return null;
108: else
109: return schemaSet;
110: }
111:
112: public NGCCRuntimeEx newNGCCRuntime() {
113: return new NGCCRuntimeEx(this );
114: }
115:
116: /** Once an error is detected, this flag is set to true. */
117: private boolean hadError = false;
118:
119: /** Turns on the error flag. */
120: void setErrorFlag() {
121: hadError = true;
122: }
123:
124: /**
125: * PatchManager implementation, which is accessible only from
126: * NGCCRuntimEx.
127: */
128: final PatcherManager patcherManager = new PatcherManager() {
129: public void addPatcher(Patch patch) {
130: patchers.add(patch);
131: }
132:
133: public void addErrorChecker(Patch patch) {
134: errorCheckers.add(patch);
135: }
136:
137: public void reportError(String msg, Locator src)
138: throws SAXException {
139: // set a flag to true to avoid returning a corrupted object.
140: setErrorFlag();
141:
142: SAXParseException e = new SAXParseException(msg, src);
143: if (errorHandler == null)
144: throw e;
145: else
146: errorHandler.error(e);
147: }
148: };
149:
150: /**
151: * ErrorHandler proxy to turn on the hadError flag when an error
152: * is found.
153: */
154: final ErrorHandler errorHandler = new ErrorHandler() {
155: private ErrorHandler getErrorHandler() {
156: if (owner.getErrorHandler() == null)
157: return noopHandler;
158: else
159: return owner.getErrorHandler();
160: }
161:
162: public void warning(SAXParseException e) throws SAXException {
163: getErrorHandler().warning(e);
164: }
165:
166: public void error(SAXParseException e) throws SAXException {
167: setErrorFlag();
168: getErrorHandler().error(e);
169: }
170:
171: public void fatalError(SAXParseException e) throws SAXException {
172: setErrorFlag();
173: getErrorHandler().fatalError(e);
174: }
175: };
176:
177: /**
178: * {@link ErrorHandler} that does nothing.
179: */
180: final ErrorHandler noopHandler = new ErrorHandler() {
181: public void warning(SAXParseException e) {
182: }
183:
184: public void error(SAXParseException e) {
185: }
186:
187: public void fatalError(SAXParseException e) {
188: setErrorFlag();
189: }
190: };
191: }
|