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