View Javadoc
1   /*
2    * reserved comment block
3    * DO NOT REMOVE OR ALTER!
4    */
5   /*
6    * Copyright 2005 The Apache Software Foundation.
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   *      http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package com.sun.org.apache.xerces.internal.parsers;
22  
23  import com.sun.org.apache.xerces.internal.impl.Constants;
24  import com.sun.org.apache.xerces.internal.util.FeatureState;
25  import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
26  import com.sun.org.apache.xerces.internal.util.SymbolTable;
27  import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
28  import com.sun.org.apache.xerces.internal.xinclude.XIncludeNamespaceSupport;
29  import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
30  import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
31  import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
32  import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
33  import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
34  import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
35  
36  /**
37   * This class is the configuration used to parse XML 1.0 and XML 1.1 documents
38   * and provides support for XInclude. This is the default Xerces configuration.
39   *
40   * @author Michael Glavassevich, IBM
41   *
42   * @version $Id: XIncludeAwareParserConfiguration.java,v 1.5 2010-11-01 04:40:10 joehw Exp $
43   */
44  public class XIncludeAwareParserConfiguration extends XML11Configuration {
45  
46      /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
47      protected static final String ALLOW_UE_AND_NOTATION_EVENTS =
48          Constants.SAX_FEATURE_PREFIX + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
49  
50      /** Feature identifier: fixup base URIs. */
51      protected static final String XINCLUDE_FIXUP_BASE_URIS =
52          Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_BASE_URIS_FEATURE;
53  
54      /** Feature identifier: fixup language. */
55      protected static final String XINCLUDE_FIXUP_LANGUAGE =
56          Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
57  
58      /** Feature identifier: XInclude processing */
59      protected static final String XINCLUDE_FEATURE =
60          Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
61  
62      /** Property identifier: error reporter. */
63      protected static final String XINCLUDE_HANDLER =
64          Constants.XERCES_PROPERTY_PREFIX + Constants.XINCLUDE_HANDLER_PROPERTY;
65  
66      /** Property identifier: error reporter. */
67      protected static final String NAMESPACE_CONTEXT =
68          Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
69  
70      //
71      // Components
72      //
73  
74      /** XInclude handler. */
75      protected XIncludeHandler fXIncludeHandler;
76  
77      /** Non-XInclude NamespaceContext. */
78      protected NamespaceSupport fNonXIncludeNSContext;
79  
80      /** XInclude NamespaceContext. */
81      protected XIncludeNamespaceSupport fXIncludeNSContext;
82  
83      /** Current NamespaceContext. */
84      protected NamespaceContext fCurrentNSContext;
85  
86      /** Flag indicating whether XInclude processsing is enabled. */
87      protected boolean fXIncludeEnabled = false;
88  
89      /** Default constructor. */
90      public XIncludeAwareParserConfiguration() {
91          this(null, null, null);
92      } // <init>()
93  
94      /**
95       * Constructs a parser configuration using the specified symbol table.
96       *
97       * @param symbolTable The symbol table to use.
98       */
99      public XIncludeAwareParserConfiguration(SymbolTable symbolTable) {
100         this(symbolTable, null, null);
101     } // <init>(SymbolTable)
102 
103     /**
104      * Constructs a parser configuration using the specified symbol table and
105      * grammar pool.
106      * <p>
107      *
108      * @param symbolTable The symbol table to use.
109      * @param grammarPool The grammar pool to use.
110      */
111     public XIncludeAwareParserConfiguration(
112             SymbolTable symbolTable,
113             XMLGrammarPool grammarPool) {
114         this(symbolTable, grammarPool, null);
115     } // <init>(SymbolTable,XMLGrammarPool)
116 
117     /**
118      * Constructs a parser configuration using the specified symbol table,
119      * grammar pool, and parent settings.
120      * <p>
121      *
122      * @param symbolTable    The symbol table to use.
123      * @param grammarPool    The grammar pool to use.
124      * @param parentSettings The parent settings.
125      */
126     public XIncludeAwareParserConfiguration(
127             SymbolTable symbolTable,
128             XMLGrammarPool grammarPool,
129             XMLComponentManager parentSettings) {
130         super(symbolTable, grammarPool, parentSettings);
131 
132         final String[] recognizedFeatures = {
133                 ALLOW_UE_AND_NOTATION_EVENTS,
134                 XINCLUDE_FIXUP_BASE_URIS,
135                 XINCLUDE_FIXUP_LANGUAGE
136         };
137         addRecognizedFeatures(recognizedFeatures);
138 
139         // add default recognized properties
140         final String[] recognizedProperties =
141         { XINCLUDE_HANDLER, NAMESPACE_CONTEXT };
142         addRecognizedProperties(recognizedProperties);
143 
144         setFeature(ALLOW_UE_AND_NOTATION_EVENTS, true);
145         setFeature(XINCLUDE_FIXUP_BASE_URIS, true);
146         setFeature(XINCLUDE_FIXUP_LANGUAGE, true);
147 
148         fNonXIncludeNSContext = new NamespaceSupport();
149         fCurrentNSContext = fNonXIncludeNSContext;
150         setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
151     }
152 
153 
154     /** Configures the pipeline. */
155     protected void configurePipeline() {
156         super.configurePipeline();
157         if (fXIncludeEnabled) {
158             // If the XInclude handler was not in the pipeline insert it.
159             if (fXIncludeHandler == null) {
160                 fXIncludeHandler = new XIncludeHandler();
161                 // add XInclude component
162                 setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
163                 addCommonComponent(fXIncludeHandler);
164                 fXIncludeHandler.reset(this);
165             }
166             // Setup NamespaceContext
167             if (fCurrentNSContext != fXIncludeNSContext) {
168                 if (fXIncludeNSContext == null) {
169                     fXIncludeNSContext = new XIncludeNamespaceSupport();
170                 }
171                 fCurrentNSContext = fXIncludeNSContext;
172                 setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
173             }
174             //configure DTD pipeline
175             fDTDScanner.setDTDHandler(fDTDProcessor);
176             fDTDProcessor.setDTDSource(fDTDScanner);
177             fDTDProcessor.setDTDHandler(fXIncludeHandler);
178             fXIncludeHandler.setDTDSource(fDTDProcessor);
179             fXIncludeHandler.setDTDHandler(fDTDHandler);
180             if (fDTDHandler != null) {
181                 fDTDHandler.setDTDSource(fXIncludeHandler);
182             }
183 
184             // configure XML document pipeline: insert after DTDValidator and
185             // before XML Schema validator
186             XMLDocumentSource prev = null;
187             if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
188                 // we don't have to worry about fSchemaValidator being null, since
189                 // super.configurePipeline() instantiated it if the feature was set
190                 prev = fSchemaValidator.getDocumentSource();
191             }
192             // Otherwise, insert after the last component in the pipeline
193             else {
194                 prev = fLastComponent;
195                 fLastComponent = fXIncludeHandler;
196             }
197 
198             XMLDocumentHandler next = prev.getDocumentHandler();
199             prev.setDocumentHandler(fXIncludeHandler);
200             fXIncludeHandler.setDocumentSource(prev);
201             if (next != null) {
202                 fXIncludeHandler.setDocumentHandler(next);
203                 next.setDocumentSource(fXIncludeHandler);
204             }
205         }
206         else {
207             // Setup NamespaceContext
208             if (fCurrentNSContext != fNonXIncludeNSContext) {
209                 fCurrentNSContext = fNonXIncludeNSContext;
210                 setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
211             }
212         }
213     } // configurePipeline()
214 
215     protected void configureXML11Pipeline() {
216         super.configureXML11Pipeline();
217         if (fXIncludeEnabled) {
218             // If the XInclude handler was not in the pipeline insert it.
219             if (fXIncludeHandler == null) {
220                 fXIncludeHandler = new XIncludeHandler();
221                 // add XInclude component
222                 setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
223                 addCommonComponent(fXIncludeHandler);
224                 fXIncludeHandler.reset(this);
225             }
226             // Setup NamespaceContext
227             if (fCurrentNSContext != fXIncludeNSContext) {
228                 if (fXIncludeNSContext == null) {
229                     fXIncludeNSContext = new XIncludeNamespaceSupport();
230                 }
231                 fCurrentNSContext = fXIncludeNSContext;
232                 setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
233             }
234             // configure XML 1.1. DTD pipeline
235             fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
236             fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
237             fXML11DTDProcessor.setDTDHandler(fXIncludeHandler);
238             fXIncludeHandler.setDTDSource(fXML11DTDProcessor);
239             fXIncludeHandler.setDTDHandler(fDTDHandler);
240             if (fDTDHandler != null) {
241                 fDTDHandler.setDTDSource(fXIncludeHandler);
242             }
243 
244             // configure XML document pipeline: insert after DTDValidator and
245             // before XML Schema validator
246             XMLDocumentSource prev = null;
247             if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
248                 // we don't have to worry about fSchemaValidator being null, since
249                 // super.configurePipeline() instantiated it if the feature was set
250                 prev = fSchemaValidator.getDocumentSource();
251             }
252             // Otherwise, insert after the last component in the pipeline
253             else {
254                 prev = fLastComponent;
255                 fLastComponent = fXIncludeHandler;
256             }
257 
258             XMLDocumentHandler next = prev.getDocumentHandler();
259             prev.setDocumentHandler(fXIncludeHandler);
260             fXIncludeHandler.setDocumentSource(prev);
261             if (next != null) {
262                 fXIncludeHandler.setDocumentHandler(next);
263                 next.setDocumentSource(fXIncludeHandler);
264             }
265         }
266         else {
267             // Setup NamespaceContext
268             if (fCurrentNSContext != fNonXIncludeNSContext) {
269                 fCurrentNSContext = fNonXIncludeNSContext;
270                 setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
271             }
272         }
273     } // configureXML11Pipeline()
274 
275     public FeatureState getFeatureState(String featureId)
276         throws XMLConfigurationException {
277         if (featureId.equals(PARSER_SETTINGS)) {
278             return FeatureState.is(fConfigUpdated);
279         }
280         else if (featureId.equals(XINCLUDE_FEATURE)) {
281             return FeatureState.is(fXIncludeEnabled);
282         }
283         return super.getFeatureState0(featureId);
284 
285     } // getFeature(String):boolean
286 
287     public void setFeature(String featureId, boolean state)
288         throws XMLConfigurationException {
289         if (featureId.equals(XINCLUDE_FEATURE)) {
290             fXIncludeEnabled = state;
291             fConfigUpdated = true;
292             return;
293         }
294         super.setFeature(featureId,state);
295     }
296 
297 }