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  */
  43 public class XIncludeAwareParserConfiguration extends XML11Configuration {
  44 
  45     /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
  46     protected static final String ALLOW_UE_AND_NOTATION_EVENTS =
  47         Constants.SAX_FEATURE_PREFIX + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
  48 
  49     /** Feature identifier: fixup base URIs. */
  50     protected static final String XINCLUDE_FIXUP_BASE_URIS =
  51         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_BASE_URIS_FEATURE;
  52 
  53     /** Feature identifier: fixup language. */
  54     protected static final String XINCLUDE_FIXUP_LANGUAGE =
  55         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE;
  56 
  57     /** Feature identifier: XInclude processing */
  58     protected static final String XINCLUDE_FEATURE =
  59         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
  60 
  61     /** Property identifier: error reporter. */
  62     protected static final String XINCLUDE_HANDLER =
  63         Constants.XERCES_PROPERTY_PREFIX + Constants.XINCLUDE_HANDLER_PROPERTY;
  64 
  65     /** Property identifier: error reporter. */
  66     protected static final String NAMESPACE_CONTEXT =
  67         Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
  68 
  69     //
  70     // Components
  71     //
  72 
  73     /** XInclude handler. */
  74     protected XIncludeHandler fXIncludeHandler;
  75 
  76     /** Non-XInclude NamespaceContext. */
  77     protected NamespaceSupport fNonXIncludeNSContext;
  78 
  79     /** XInclude NamespaceContext. */
  80     protected XIncludeNamespaceSupport fXIncludeNSContext;
  81 
  82     /** Current NamespaceContext. */
  83     protected NamespaceContext fCurrentNSContext;
  84 
  85     /** Flag indicating whether XInclude processsing is enabled. */
  86     protected boolean fXIncludeEnabled = false;
  87 
  88     /** Default constructor. */
  89     public XIncludeAwareParserConfiguration() {
  90         this(null, null, null);
  91     } // <init>()
  92 
  93     /**
  94      * Constructs a parser configuration using the specified symbol table.
  95      *
  96      * @param symbolTable The symbol table to use.
  97      */
  98     public XIncludeAwareParserConfiguration(SymbolTable symbolTable) {
  99         this(symbolTable, null, null);
 100     } // <init>(SymbolTable)
 101 
 102     /**
 103      * Constructs a parser configuration using the specified symbol table and
 104      * grammar pool.
 105      * <p>
 106      *
 107      * @param symbolTable The symbol table to use.
 108      * @param grammarPool The grammar pool to use.
 109      */
 110     public XIncludeAwareParserConfiguration(
 111             SymbolTable symbolTable,
 112             XMLGrammarPool grammarPool) {
 113         this(symbolTable, grammarPool, null);
 114     } // <init>(SymbolTable,XMLGrammarPool)
 115 
 116     /**
 117      * Constructs a parser configuration using the specified symbol table,
 118      * grammar pool, and parent settings.
 119      * <p>
 120      *
 121      * @param symbolTable    The symbol table to use.
 122      * @param grammarPool    The grammar pool to use.
 123      * @param parentSettings The parent settings.
 124      */
 125     public XIncludeAwareParserConfiguration(
 126             SymbolTable symbolTable,
 127             XMLGrammarPool grammarPool,
 128             XMLComponentManager parentSettings) {
 129         super(symbolTable, grammarPool, parentSettings);
 130 
 131         final String[] recognizedFeatures = {
 132                 ALLOW_UE_AND_NOTATION_EVENTS,
 133                 XINCLUDE_FIXUP_BASE_URIS,
 134                 XINCLUDE_FIXUP_LANGUAGE
 135         };
 136         addRecognizedFeatures(recognizedFeatures);
 137 
 138         // add default recognized properties
 139         final String[] recognizedProperties =
 140         { XINCLUDE_HANDLER, NAMESPACE_CONTEXT };
 141         addRecognizedProperties(recognizedProperties);
 142 
 143         setFeature(ALLOW_UE_AND_NOTATION_EVENTS, true);
 144         setFeature(XINCLUDE_FIXUP_BASE_URIS, true);
 145         setFeature(XINCLUDE_FIXUP_LANGUAGE, true);
 146 
 147         fNonXIncludeNSContext = new NamespaceSupport();
 148         fCurrentNSContext = fNonXIncludeNSContext;
 149         setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
 150     }
 151 
 152 
 153     /** Configures the pipeline. */
 154     protected void configurePipeline() {
 155         super.configurePipeline();
 156         if (fXIncludeEnabled) {
 157             // If the XInclude handler was not in the pipeline insert it.
 158             if (fXIncludeHandler == null) {
 159                 fXIncludeHandler = new XIncludeHandler();
 160                 // add XInclude component
 161                 setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
 162                 addCommonComponent(fXIncludeHandler);
 163                 fXIncludeHandler.reset(this);
 164             }
 165             // Setup NamespaceContext
 166             if (fCurrentNSContext != fXIncludeNSContext) {
 167                 if (fXIncludeNSContext == null) {
 168                     fXIncludeNSContext = new XIncludeNamespaceSupport();
 169                 }
 170                 fCurrentNSContext = fXIncludeNSContext;
 171                 setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
 172             }
 173             //configure DTD pipeline
 174             fDTDScanner.setDTDHandler(fDTDProcessor);
 175             fDTDProcessor.setDTDSource(fDTDScanner);
 176             fDTDProcessor.setDTDHandler(fXIncludeHandler);
 177             fXIncludeHandler.setDTDSource(fDTDProcessor);
 178             fXIncludeHandler.setDTDHandler(fDTDHandler);
 179             if (fDTDHandler != null) {
 180                 fDTDHandler.setDTDSource(fXIncludeHandler);
 181             }
 182 
 183             // configure XML document pipeline: insert after DTDValidator and
 184             // before XML Schema validator
 185             XMLDocumentSource prev = null;
 186             if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
 187                 // we don't have to worry about fSchemaValidator being null, since
 188                 // super.configurePipeline() instantiated it if the feature was set
 189                 prev = fSchemaValidator.getDocumentSource();
 190             }
 191             // Otherwise, insert after the last component in the pipeline
 192             else {
 193                 prev = fLastComponent;
 194                 fLastComponent = fXIncludeHandler;
 195             }
 196 
 197             XMLDocumentHandler next = prev.getDocumentHandler();
 198             prev.setDocumentHandler(fXIncludeHandler);
 199             fXIncludeHandler.setDocumentSource(prev);
 200             if (next != null) {
 201                 fXIncludeHandler.setDocumentHandler(next);
 202                 next.setDocumentSource(fXIncludeHandler);
 203             }
 204         }
 205         else {
 206             // Setup NamespaceContext
 207             if (fCurrentNSContext != fNonXIncludeNSContext) {
 208                 fCurrentNSContext = fNonXIncludeNSContext;
 209                 setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
 210             }
 211         }
 212     } // configurePipeline()
 213 
 214     protected void configureXML11Pipeline() {
 215         super.configureXML11Pipeline();
 216         if (fXIncludeEnabled) {
 217             // If the XInclude handler was not in the pipeline insert it.
 218             if (fXIncludeHandler == null) {
 219                 fXIncludeHandler = new XIncludeHandler();
 220                 // add XInclude component
 221                 setProperty(XINCLUDE_HANDLER, fXIncludeHandler);
 222                 addCommonComponent(fXIncludeHandler);
 223                 fXIncludeHandler.reset(this);
 224             }
 225             // Setup NamespaceContext
 226             if (fCurrentNSContext != fXIncludeNSContext) {
 227                 if (fXIncludeNSContext == null) {
 228                     fXIncludeNSContext = new XIncludeNamespaceSupport();
 229                 }
 230                 fCurrentNSContext = fXIncludeNSContext;
 231                 setProperty(NAMESPACE_CONTEXT, fXIncludeNSContext);
 232             }
 233             // configure XML 1.1. DTD pipeline
 234             fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
 235             fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
 236             fXML11DTDProcessor.setDTDHandler(fXIncludeHandler);
 237             fXIncludeHandler.setDTDSource(fXML11DTDProcessor);
 238             fXIncludeHandler.setDTDHandler(fDTDHandler);
 239             if (fDTDHandler != null) {
 240                 fDTDHandler.setDTDSource(fXIncludeHandler);
 241             }
 242 
 243             // configure XML document pipeline: insert after DTDValidator and
 244             // before XML Schema validator
 245             XMLDocumentSource prev = null;
 246             if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
 247                 // we don't have to worry about fSchemaValidator being null, since
 248                 // super.configurePipeline() instantiated it if the feature was set
 249                 prev = fSchemaValidator.getDocumentSource();
 250             }
 251             // Otherwise, insert after the last component in the pipeline
 252             else {
 253                 prev = fLastComponent;
 254                 fLastComponent = fXIncludeHandler;
 255             }
 256 
 257             XMLDocumentHandler next = prev.getDocumentHandler();
 258             prev.setDocumentHandler(fXIncludeHandler);
 259             fXIncludeHandler.setDocumentSource(prev);
 260             if (next != null) {
 261                 fXIncludeHandler.setDocumentHandler(next);
 262                 next.setDocumentSource(fXIncludeHandler);
 263             }
 264         }
 265         else {
 266             // Setup NamespaceContext
 267             if (fCurrentNSContext != fNonXIncludeNSContext) {
 268                 fCurrentNSContext = fNonXIncludeNSContext;
 269                 setProperty(NAMESPACE_CONTEXT, fNonXIncludeNSContext);
 270             }
 271         }
 272     } // configureXML11Pipeline()
 273 
 274     public FeatureState getFeatureState(String featureId)
 275         throws XMLConfigurationException {
 276         if (featureId.equals(PARSER_SETTINGS)) {
 277             return FeatureState.is(fConfigUpdated);
 278         }
 279         else if (featureId.equals(XINCLUDE_FEATURE)) {
 280             return FeatureState.is(fXIncludeEnabled);
 281         }
 282         return super.getFeatureState0(featureId);
 283 
 284     } // getFeature(String):boolean
 285 
 286     public void setFeature(String featureId, boolean state)
 287         throws XMLConfigurationException {
 288         if (featureId.equals(XINCLUDE_FEATURE)) {
 289             fXIncludeEnabled = state;
 290             fConfigUpdated = true;
 291             return;
 292         }
 293         super.setFeature(featureId,state);
 294     }
 295 
 296 }