001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.parsers;
019:
020: import org.apache.xerces.impl.Constants;
021: import org.apache.xerces.util.NamespaceSupport;
022: import org.apache.xerces.util.SymbolTable;
023: import org.apache.xerces.xinclude.XIncludeHandler;
024: import org.apache.xerces.xinclude.XIncludeNamespaceSupport;
025: import org.apache.xerces.xni.NamespaceContext;
026: import org.apache.xerces.xni.XMLDocumentHandler;
027: import org.apache.xerces.xni.grammars.XMLGrammarPool;
028: import org.apache.xerces.xni.parser.XMLComponentManager;
029: import org.apache.xerces.xni.parser.XMLConfigurationException;
030: import org.apache.xerces.xni.parser.XMLDocumentSource;
031:
032: /**
033: * This class is the configuration used to parse XML 1.0 and XML 1.1 documents
034: * and provides support for XInclude. This is the default Xerces configuration.
035: *
036: * @author Michael Glavassevich, IBM
037: *
038: * @version $Id: XIncludeAwareParserConfiguration.java 447239 2006-09-18 05:08:26Z mrglavas $
039: */
040: public class XIncludeAwareParserConfiguration extends
041: XML11Configuration {
042:
043: /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
044: protected static final String ALLOW_UE_AND_NOTATION_EVENTS = Constants.SAX_FEATURE_PREFIX
045: + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
046:
047: /** Feature identifier: fixup base URIs. */
048: protected static final String XINCLUDE_FIXUP_BASE_URIS = Constants.XERCES_FEATURE_PREFIX
049: + Constants.XINCLUDE_FIXUP_BASE_URIS_FEATURE;
050:
051: /** Feature identifier: fixup language. */
052: protected static final String XINCLUDE_FIXUP_LANGUAGE = Constants.XERCES_FEATURE_PREFIX
053: + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
054:
055: /** Feature identifier: XInclude processing */
056: protected static final String XINCLUDE_FEATURE = Constants.XERCES_FEATURE_PREFIX
057: + Constants.XINCLUDE_FEATURE;
058:
059: /** Property identifier: error reporter. */
060: protected static final String XINCLUDE_HANDLER = Constants.XERCES_PROPERTY_PREFIX
061: + Constants.XINCLUDE_HANDLER_PROPERTY;
062:
063: /** Property identifier: error reporter. */
064: protected static final String NAMESPACE_CONTEXT = Constants.XERCES_PROPERTY_PREFIX
065: + Constants.NAMESPACE_CONTEXT_PROPERTY;
066:
067: //
068: // Components
069: //
070:
071: /** XInclude handler. */
072: protected XIncludeHandler fXIncludeHandler;
073:
074: /** Non-XInclude NamespaceContext. */
075: protected NamespaceSupport fNonXIncludeNSContext;
076:
077: /** XInclude NamespaceContext. */
078: protected XIncludeNamespaceSupport fXIncludeNSContext;
079:
080: /** Current NamespaceContext. */
081: protected NamespaceContext fCurrentNSContext;
082:
083: /** Flag indicating whether XInclude processsing is enabled. */
084: protected boolean fXIncludeEnabled = false;
085:
086: /** Default constructor. */
087: public XIncludeAwareParserConfiguration() {
088: this (null, null, null);
089: } // <init>()
090:
091: /**
092: * Constructs a parser configuration using the specified symbol table.
093: *
094: * @param symbolTable The symbol table to use.
095: */
096: public XIncludeAwareParserConfiguration(SymbolTable symbolTable) {
097: this (symbolTable, null, null);
098: } // <init>(SymbolTable)
099:
100: /**
101: * Constructs a parser configuration using the specified symbol table and
102: * grammar pool.
103: * <p>
104: *
105: * @param symbolTable The symbol table to use.
106: * @param grammarPool The grammar pool to use.
107: */
108: public XIncludeAwareParserConfiguration(SymbolTable symbolTable,
109: XMLGrammarPool grammarPool) {
110: this (symbolTable, grammarPool, null);
111: } // <init>(SymbolTable,XMLGrammarPool)
112:
113: /**
114: * Constructs a parser configuration using the specified symbol table,
115: * grammar pool, and parent settings.
116: * <p>
117: *
118: * @param symbolTable The symbol table to use.
119: * @param grammarPool The grammar pool to use.
120: * @param parentSettings The parent settings.
121: */
122: public XIncludeAwareParserConfiguration(SymbolTable symbolTable,
123: XMLGrammarPool grammarPool,
124: XMLComponentManager parentSettings) {
125: super (symbolTable, grammarPool, parentSettings);
126:
127: final String[] recognizedFeatures = {
128: ALLOW_UE_AND_NOTATION_EVENTS, XINCLUDE_FIXUP_BASE_URIS,
129: XINCLUDE_FIXUP_LANGUAGE };
130: addRecognizedFeatures(recognizedFeatures);
131:
132: // add default recognized properties
133: final String[] recognizedProperties = { XINCLUDE_HANDLER,
134: NAMESPACE_CONTEXT };
135: addRecognizedProperties(recognizedProperties);
136:
137: setFeature(ALLOW_UE_AND_NOTATION_EVENTS, true);
138: setFeature(XINCLUDE_FIXUP_BASE_URIS, true);
139: setFeature(XINCLUDE_FIXUP_LANGUAGE, true);
140:
141: fNonXIncludeNSContext = new NamespaceSupport();
142: fCurrentNSContext = fNonXIncludeNSContext;
143: setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
144: }
145:
146: /** Configures the pipeline. */
147: protected void configurePipeline() {
148: super .configurePipeline();
149: if (fXIncludeEnabled) {
150: // If the XInclude handler was not in the pipeline insert it.
151: if (fXIncludeHandler == null) {
152: fXIncludeHandler = new XIncludeHandler();
153: // add XInclude component
154: setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
155: addCommonComponent(fXIncludeHandler);
156: fXIncludeHandler.reset(this );
157: }
158: // Setup NamespaceContext
159: if (fCurrentNSContext != fXIncludeNSContext) {
160: if (fXIncludeNSContext == null) {
161: fXIncludeNSContext = new XIncludeNamespaceSupport();
162: }
163: fCurrentNSContext = fXIncludeNSContext;
164: setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
165: }
166: //configure DTD pipeline
167: fDTDScanner.setDTDHandler(fDTDProcessor);
168: fDTDProcessor.setDTDSource(fDTDScanner);
169: fDTDProcessor.setDTDHandler(fXIncludeHandler);
170: fXIncludeHandler.setDTDSource(fDTDProcessor);
171: fXIncludeHandler.setDTDHandler(fDTDHandler);
172: if (fDTDHandler != null) {
173: fDTDHandler.setDTDSource(fXIncludeHandler);
174: }
175:
176: // configure XML document pipeline: insert after DTDValidator and
177: // before XML Schema validator
178: XMLDocumentSource prev = null;
179: if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
180: // we don't have to worry about fSchemaValidator being null, since
181: // super.configurePipeline() instantiated it if the feature was set
182: prev = fSchemaValidator.getDocumentSource();
183: }
184: // Otherwise, insert after the last component in the pipeline
185: else {
186: prev = fLastComponent;
187: fLastComponent = fXIncludeHandler;
188: }
189:
190: XMLDocumentHandler next = prev.getDocumentHandler();
191: prev.setDocumentHandler(fXIncludeHandler);
192: fXIncludeHandler.setDocumentSource(prev);
193: if (next != null) {
194: fXIncludeHandler.setDocumentHandler(next);
195: next.setDocumentSource(fXIncludeHandler);
196: }
197: } else {
198: // Setup NamespaceContext
199: if (fCurrentNSContext != fNonXIncludeNSContext) {
200: fCurrentNSContext = fNonXIncludeNSContext;
201: setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
202: }
203: }
204: } // configurePipeline()
205:
206: protected void configureXML11Pipeline() {
207: super .configureXML11Pipeline();
208: if (fXIncludeEnabled) {
209: // If the XInclude handler was not in the pipeline insert it.
210: if (fXIncludeHandler == null) {
211: fXIncludeHandler = new XIncludeHandler();
212: // add XInclude component
213: setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
214: addCommonComponent(fXIncludeHandler);
215: fXIncludeHandler.reset(this );
216: }
217: // Setup NamespaceContext
218: if (fCurrentNSContext != fXIncludeNSContext) {
219: if (fXIncludeNSContext == null) {
220: fXIncludeNSContext = new XIncludeNamespaceSupport();
221: }
222: fCurrentNSContext = fXIncludeNSContext;
223: setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
224: }
225: // configure XML 1.1. DTD pipeline
226: fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
227: fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
228: fXML11DTDProcessor.setDTDHandler(fXIncludeHandler);
229: fXIncludeHandler.setDTDSource(fXML11DTDProcessor);
230: fXIncludeHandler.setDTDHandler(fDTDHandler);
231: if (fDTDHandler != null) {
232: fDTDHandler.setDTDSource(fXIncludeHandler);
233: }
234:
235: // configure XML document pipeline: insert after DTDValidator and
236: // before XML Schema validator
237: XMLDocumentSource prev = null;
238: if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
239: // we don't have to worry about fSchemaValidator being null, since
240: // super.configurePipeline() instantiated it if the feature was set
241: prev = fSchemaValidator.getDocumentSource();
242: }
243: // Otherwise, insert after the last component in the pipeline
244: else {
245: prev = fLastComponent;
246: fLastComponent = fXIncludeHandler;
247: }
248:
249: XMLDocumentHandler next = prev.getDocumentHandler();
250: prev.setDocumentHandler(fXIncludeHandler);
251: fXIncludeHandler.setDocumentSource(prev);
252: if (next != null) {
253: fXIncludeHandler.setDocumentHandler(next);
254: next.setDocumentSource(fXIncludeHandler);
255: }
256: } else {
257: // Setup NamespaceContext
258: if (fCurrentNSContext != fNonXIncludeNSContext) {
259: fCurrentNSContext = fNonXIncludeNSContext;
260: setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
261: }
262: }
263: } // configureXML11Pipeline()
264:
265: public boolean getFeature(String featureId)
266: throws XMLConfigurationException {
267: if (featureId.equals(PARSER_SETTINGS)) {
268: return fConfigUpdated;
269: } else if (featureId.equals(XINCLUDE_FEATURE)) {
270: return fXIncludeEnabled;
271: }
272: return super .getFeature0(featureId);
273:
274: } // getFeature(String):boolean
275:
276: public void setFeature(String featureId, boolean state)
277: throws XMLConfigurationException {
278: if (featureId.equals(XINCLUDE_FEATURE)) {
279: fXIncludeEnabled = state;
280: fConfigUpdated = true;
281: return;
282: }
283: super.setFeature(featureId, state);
284: }
285:
286: }
|