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.xinclude;
  23 
  24 
  25 import java.util.Enumeration;
  26 import java.util.StringTokenizer;
  27 import java.util.Stack;
  28 
  29 import com.sun.org.apache.xerces.internal.impl.Constants;
  30 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  31 import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
  32 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
  33 import com.sun.org.apache.xerces.internal.xni.Augmentations;
  34 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
  35 import com.sun.org.apache.xerces.internal.xni.QName;
  36 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
  37 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  38 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  39 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
  40 import com.sun.org.apache.xerces.internal.xni.XMLString;
  41 import com.sun.org.apache.xerces.internal.xni.XNIException;
  42 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  43 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  44 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  45 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  46 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  47 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  48 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator;
  49 /**
  50  * @author Arun Yadav, Sun Microsystem
  51  */
  52 public class XPointerElementHandler implements XPointerSchema {
  53 
  54 
  55     // recognized features and properties
  56 
  57     /** Property identifier: error handler. */
  58     protected static final String ERROR_REPORTER =
  59     Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  60 
  61     /** Property identifier: grammar pool . */
  62     protected static final String GRAMMAR_POOL =
  63     Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  64 
  65     /** Property identifier: grammar pool . */
  66     protected static final String ENTITY_RESOLVER =
  67     Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
  68 
  69     protected static final String XPOINTER_SCHEMA =
  70     Constants.XERCES_PROPERTY_PREFIX + Constants.XPOINTER_SCHEMA_PROPERTY;
  71 
  72     /** Recognized features. */
  73     private static final String[] RECOGNIZED_FEATURES = {
  74     };
  75 
  76     /** Feature defaults. */
  77     private static final Boolean[] FEATURE_DEFAULTS = {
  78     };
  79 
  80     /** Recognized properties. */
  81 
  82     private static final String[] RECOGNIZED_PROPERTIES =
  83     { ERROR_REPORTER, GRAMMAR_POOL, ENTITY_RESOLVER, XPOINTER_SCHEMA };
  84 
  85     /** Property defaults. */
  86     private static final Object[] PROPERTY_DEFAULTS = { null, null, null,null };
  87 
  88     // Data
  89 
  90     protected XMLDocumentHandler fDocumentHandler;
  91     protected XMLDocumentSource fDocumentSource;
  92 
  93     protected XIncludeHandler fParentXIncludeHandler;
  94 
  95     protected XMLLocator fDocLocation;
  96     protected XIncludeNamespaceSupport fNamespaceContext;
  97     protected XMLErrorReporter fErrorReporter;
  98     protected XMLGrammarPool fGrammarPool;
  99     protected XMLGrammarDescription fGrammarDesc;
 100     protected DTDGrammar fDTDGrammar;
 101     protected XMLEntityResolver fEntityResolver;
 102     protected ParserConfigurationSettings fSettings;
 103     //protected String fPointerSchema;
 104     protected StringBuffer fPointer;
 105     private int elemCount = 0;
 106 
 107 
 108     // The current element depth.
 109     // This is used to access the appropriate level of the following stacks.
 110     private int fDepth;
 111 
 112     // The depth of the first element to actually be part of the result infoset.
 113     // This will normally be 1, but it could be larger when the top-level item
 114     // is an include, and processing goes to the fallback.
 115     private int fRootDepth;
 116 
 117     // this value must be at least 1
 118     private static final int INITIAL_SIZE = 8;
 119 
 120 
 121     // Used to ensure that fallbacks are always children of include elements,
 122     // and that include elements are never children of other include elements.
 123     // An index contains true if the ancestor of the current element which resides
 124     // at that depth was an include element.
 125     private boolean[] fSawInclude = new boolean[INITIAL_SIZE];
 126 
 127 
 128     // Ensures that only one fallback element can be at a single depth.
 129     // An index contains true if we have seen any fallback elements at that depth,
 130     // and it is only reset to false when the end tag of the parent is encountered.
 131     private boolean[] fSawFallback = new boolean[INITIAL_SIZE];
 132 
 133 
 134     // The state of the processor at each given depth.
 135     private int[] fState = new int[INITIAL_SIZE];
 136 
 137     QName foundElement = null;
 138     boolean skip = false;
 139     // Constructors
 140 
 141     public XPointerElementHandler() {
 142 
 143 
 144         fDepth = 0;
 145         fRootDepth = 0;
 146         fSawFallback[fDepth] = false;
 147         fSawInclude[fDepth] = false;
 148         fSchemaName="element";
 149 
 150 
 151     }
 152 
 153     // START OF IMPLEMENTATION OF XMLComponent methods //////
 154 
 155     public void reset(){
 156         elemCount =0;
 157         fPointerToken = null;
 158         fCurrentTokenint=0;
 159         fCurrentTokenString=null;
 160         fCurrentTokenType=0 ;
 161         fElementCount =0;
 162         fCurrentToken =0;
 163         includeElement = false;
 164         foundElement = null;
 165         skip = false;
 166         fSubResourceIdentified=false;
 167     }
 168 
 169     public void reset(XMLComponentManager componentManager)
 170     throws XNIException {
 171         fNamespaceContext = null;
 172         elemCount =0;
 173         fDepth = 0;
 174         fRootDepth = 0;
 175         fPointerToken = null;
 176         fCurrentTokenint=0;
 177         fCurrentTokenString=null;
 178         fCurrentTokenType=0 ;
 179         foundElement = null;
 180         includeElement = false;
 181         skip = false;
 182         fSubResourceIdentified=false;
 183 
 184 
 185 
 186 
 187         try {
 188             setErrorReporter(
 189             (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER));
 190         }
 191         catch (XMLConfigurationException e) {
 192             fErrorReporter = null;
 193         }
 194         try {
 195             fGrammarPool =
 196             (XMLGrammarPool)componentManager.getProperty(GRAMMAR_POOL);
 197         }
 198         catch (XMLConfigurationException e) {
 199             fGrammarPool = null;
 200         }
 201         try {
 202             fEntityResolver =
 203             (XMLEntityResolver)componentManager.getProperty(
 204             ENTITY_RESOLVER);
 205         }
 206         catch (XMLConfigurationException e) {
 207             fEntityResolver = null;
 208         }
 209 
 210         fSettings = new ParserConfigurationSettings();
 211 
 212         Enumeration xercesFeatures = Constants.getXercesFeatures();
 213         while (xercesFeatures.hasMoreElements()) {
 214             String featureId = (String)xercesFeatures.nextElement();
 215             fSettings.addRecognizedFeatures(new String[] { featureId });
 216             try {
 217                 fSettings.setFeature(
 218                 featureId,
 219                 componentManager.getFeature(featureId));
 220             }
 221             catch (XMLConfigurationException e) {
 222                 // componentManager doesn't support this feature,
 223                 // so we won't worry about it
 224             }
 225         }
 226 /*              try{
 227           dtdValidator =   (XMLDTDValidator)componentManager.getProperty( Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY);
 228                 }Catch(Exception ex){
 229                         ex.printStackTrace();
 230                 }*/
 231 
 232     } // reset(XMLComponentManager)
 233 
 234     /**
 235      * Returns a list of feature identifiers that are recognized by
 236      * this component. This method may return null if no features
 237      * are recognized by this component.
 238      */
 239     public String[] getRecognizedFeatures() {
 240         return RECOGNIZED_FEATURES;
 241     } // getRecognizedFeatures():String[]
 242 
 243     /**
 244      * Sets the state of a feature. This method is called by the component
 245      * manager any time after reset when a feature changes state.
 246      * <p>
 247      * <strong>Note:</strong> Components should silently ignore features
 248      * that do not affect the operation of the component.
 249      *
 250      * @param featureId The feature identifier.
 251      * @param state     The state of the feature.
 252      *
 253      * @throws SAXNotRecognizedException The component should not throw
 254      *                                   this exception.
 255      * @throws SAXNotSupportedException The component should not throw
 256      *                                  this exception.
 257      */
 258     public void setFeature(String featureId, boolean state)
 259     throws XMLConfigurationException {
 260         if (fSettings != null) {
 261             fSettings.setFeature(featureId, state);
 262         }
 263 
 264     } // setFeature(String,boolean)
 265 
 266     /**
 267      * Returns a list of property identifiers that are recognized by
 268      * this component. This method may return null if no properties
 269      * are recognized by this component.
 270      */
 271     public String[] getRecognizedProperties() {
 272         return RECOGNIZED_PROPERTIES;
 273     } // getRecognizedProperties():String[]
 274 
 275     /**
 276      * Sets the value of a property. This method is called by the component
 277      * manager any time after reset when a property changes value.
 278      * <p>
 279      * <strong>Note:</strong> Components should silently ignore properties
 280      * that do not affect the operation of the component.
 281      *
 282      * @param propertyId The property identifier.
 283      * @param value      The value of the property.
 284      *
 285      * @throws SAXNotRecognizedException The component should not throw
 286      *                                   this exception.
 287      * @throws SAXNotSupportedException The component should not throw
 288      *                                  this exception.
 289      */
 290     public void setProperty(String propertyId, Object value)
 291     throws XMLConfigurationException {
 292         if (propertyId.equals(ERROR_REPORTER)) {
 293             setErrorReporter((XMLErrorReporter)value);
 294         }
 295         if (propertyId.equals(GRAMMAR_POOL)) {
 296             fGrammarPool = (XMLGrammarPool)value;
 297         }
 298         if (propertyId.equals(ENTITY_RESOLVER)) {
 299             fEntityResolver = (XMLEntityResolver)value;
 300         }
 301 
 302     } // setProperty(String,Object)
 303 
 304     /**
 305      * Returns the default state for a feature, or null if this
 306      * component does not want to report a default value for this
 307      * feature.
 308      *
 309      * @param featureId The feature identifier.
 310      *
 311      * @since Xerces 2.2.0
 312      */
 313     public Boolean getFeatureDefault(String featureId) {
 314         for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
 315             if (RECOGNIZED_FEATURES[i].equals(featureId)) {
 316                 return FEATURE_DEFAULTS[i];
 317             }
 318         }
 319         return null;
 320     } // getFeatureDefault(String):Boolean
 321 
 322     /**
 323      * Returns the default state for a property, or null if this
 324      * component does not want to report a default value for this
 325      * property.
 326      *
 327      * @param propertyId The property identifier.
 328      *
 329      * @since Xerces 2.2.0
 330      */
 331     public Object getPropertyDefault(String propertyId) {
 332         for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
 333             if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
 334                 return PROPERTY_DEFAULTS[i];
 335             }
 336         }
 337         return null;
 338     } // getPropertyDefault(String):Object
 339 
 340     private void setErrorReporter(XMLErrorReporter reporter) {
 341         fErrorReporter = reporter;
 342         if (fErrorReporter != null) {
 343             fErrorReporter.putMessageFormatter(
 344             XIncludeMessageFormatter.XINCLUDE_DOMAIN,
 345             new XIncludeMessageFormatter());
 346         }
 347     }
 348     ///////// END OF IMPLEMENTATION  OF XMLComponents methods. //////////
 349 
 350 
 351 
 352     //////// START OF  IMPLEMENTATION OF XMLDOCUMENTSOURCE INTERFACE /////////
 353 
 354     public void setDocumentHandler(XMLDocumentHandler handler) {
 355         fDocumentHandler = handler;
 356     }
 357 
 358     public XMLDocumentHandler getDocumentHandler() {
 359         return fDocumentHandler;
 360     }
 361 
 362     ///////   END OF IMPLENTATION OF XMLDOCUMENTSOURCE INTERFACE ///////////
 363 
 364 
 365 
 366 
 367     /////////////// Implementation of XPointerSchema Methods //////////////////////
 368 
 369     String fSchemaName;
 370     String fSchemaPointer;
 371     boolean fSubResourceIdentified;
 372     /**
 373      * set the Schema Name  eg element , xpointer
 374      */
 375     public void setXPointerSchemaName(String schemaName){
 376         fSchemaName = schemaName;
 377     }
 378 
 379     /**
 380      * Return  Schema Name  eg element , xpointer
 381      *
 382      */
 383     public String getXpointerSchemaName(){
 384         return fSchemaName;
 385     }
 386 
 387     /**
 388      * Parent Contenhandler for the this contenthandler.
 389      * // not sure about the parameter type. It can be Contenthandler instead of Object type.
 390      */
 391     public void setParent(Object parent){
 392         fParentXIncludeHandler = (XIncludeHandler)parent;
 393     }
 394 
 395 
 396     /**
 397      * return the Parent Contenthandler
 398      */
 399     public Object getParent(){
 400         return fParentXIncludeHandler;
 401     }
 402 
 403     /**
 404      * Content of the XPointer Schema. Xpath to be resolved.
 405      */
 406     public void setXPointerSchemaPointer(String content){
 407         fSchemaPointer = content;
 408     }
 409 
 410     /**
 411      * Return the XPointer Schema.
 412      */
 413     public String getXPointerSchemaPointer(){
 414         return fSchemaPointer;
 415     }
 416 
 417     public boolean isSubResourceIndentified(){
 418         return fSubResourceIdentified;
 419     }
 420 
 421     ///////////End Implementation of XPointerSchema Methods //////////////////////
 422 
 423 
 424 
 425     //////////// Tokens Playground ///////////////////
 426 
 427     Stack fPointerToken = new Stack();
 428     int  fCurrentTokenint=0;
 429     String fCurrentTokenString=null;
 430     int fCurrentTokenType=0 ;// 0 Notype; 1 for integer; 2 for string.
 431 
 432     public void getTokens(){
 433         fSchemaPointer = fSchemaPointer.substring(fSchemaPointer.indexOf("(")+1, fSchemaPointer.length());
 434         StringTokenizer st = new StringTokenizer(fSchemaPointer, "/");
 435         String tempToken;
 436         Integer integerToken =null;
 437         Stack tempPointerToken = new Stack();
 438         if(fPointerToken == null){
 439             fPointerToken = new Stack();
 440         }
 441         while(st.hasMoreTokens()){
 442             tempToken=st.nextToken();
 443             try {
 444                 integerToken = Integer.valueOf(tempToken);
 445                 tempPointerToken.push(integerToken);
 446             }catch(NumberFormatException e){
 447                 tempPointerToken.push(tempToken);
 448             }
 449         }
 450         while(!tempPointerToken.empty()){
 451             fPointerToken.push(tempPointerToken.pop());
 452         }
 453     }//getTokens
 454 
 455 
 456     public boolean hasMoreToken(){
 457         if(fPointerToken.isEmpty())
 458             return false;
 459         else
 460             return true;
 461     }
 462 
 463     public boolean getNextToken(){
 464         Object currentToken;
 465         if (!fPointerToken.isEmpty()){
 466             currentToken = fPointerToken.pop();
 467             if(currentToken instanceof Integer){
 468                 fCurrentTokenint = ((Integer)currentToken).intValue();
 469                 fCurrentTokenType = 1;
 470             }
 471             else{
 472                 fCurrentTokenString = ((String)currentToken).toString();
 473                 fCurrentTokenType = 2;
 474             }
 475             return true;
 476         }
 477         else {
 478             return false;
 479         }
 480     }
 481 
 482     private boolean isIdAttribute(XMLAttributes attributes,Augmentations augs, int index) {
 483         Object o = augs.getItem(Constants.ID_ATTRIBUTE);
 484         if( o instanceof Boolean )
 485             return ((Boolean)o).booleanValue();
 486         return "ID".equals(attributes.getType(index));
 487     }
 488 
 489     public boolean checkStringToken(QName element, XMLAttributes attributes){
 490         QName cacheQName = null;
 491         String id =null;
 492         String rawname =null;
 493         QName attrName = new QName();
 494         String attrType = null;
 495         String attrValue = null;
 496         int attrCount = attributes.getLength();
 497         for (int i = 0; i < attrCount; i++) {
 498             Augmentations aaugs = attributes.getAugmentations(i);
 499             attributes.getName(i,attrName);
 500             attrType = attributes.getType(i);
 501             attrValue = attributes.getValue(i);
 502             if(attrType != null && attrValue!= null && isIdAttribute(attributes,aaugs,i) && attrValue.equals(fCurrentTokenString)){
 503                 if(hasMoreToken()){
 504                     fCurrentTokenType = 0;
 505                     fCurrentTokenString = null;
 506                     return true;
 507                 }
 508                 else{
 509                     foundElement = element;
 510                     includeElement = true;
 511                     fCurrentTokenType = 0;
 512                     fCurrentTokenString = null;
 513                     fSubResourceIdentified = true;
 514                     return true;
 515                 }
 516             }
 517         }
 518         return false;
 519     }
 520 
 521     public boolean checkIntegerToken(QName element){
 522         if(!skip){
 523             fElementCount++;
 524             if(fCurrentTokenint == fElementCount){
 525                 if(hasMoreToken()){
 526                     fElementCount=0;
 527                     fCurrentTokenType = 0;
 528                     return true;
 529                 }
 530                 else{
 531                     foundElement = element;
 532                     includeElement = true;
 533                     fCurrentTokenType = 0;
 534                     fElementCount=0;
 535                     fSubResourceIdentified =true;
 536                     return true;
 537                 }
 538             }else{
 539                 addQName(element);
 540                 skip = true;
 541                 return false;
 542             }
 543         }
 544         return false;
 545     }
 546 
 547     public void addQName(QName element){
 548         QName cacheQName = new QName(element);
 549         ftempCurrentElement.push(cacheQName);
 550     }
 551 
 552     ///////////  END TOKEN PLAYGROUND ///////////////
 553 
 554 
 555     /////   START OF IMPLEMTATION OF XMLDocumentHandler methods //////////
 556 
 557 
 558     public void startDocument(XMLLocator locator, String encoding,
 559     NamespaceContext namespaceContext, Augmentations augs)
 560     throws XNIException {
 561 
 562         getTokens();
 563     }
 564 
 565     public void doctypeDecl(String rootElement, String publicId, String systemId,
 566     Augmentations augs)throws XNIException {
 567     }
 568 
 569     public void xmlDecl(String version, String encoding, String standalone,
 570     Augmentations augs) throws XNIException {
 571     }
 572 
 573 
 574     public void comment(XMLString text, Augmentations augs)
 575     throws XNIException {
 576         if (fDocumentHandler != null && includeElement) {
 577             fDocumentHandler.comment(text, augs);
 578         }
 579     }
 580 
 581     public void processingInstruction(String target, XMLString data,
 582     Augmentations augs) throws XNIException {
 583         if (fDocumentHandler != null && includeElement) {
 584             fDocumentHandler.processingInstruction(target, data, augs);
 585 
 586         }
 587     }
 588 
 589     Stack  ftempCurrentElement = new Stack();
 590     int fElementCount =0;
 591     int fCurrentToken ;
 592     boolean includeElement;
 593 
 594 
 595     public void startElement(QName element, XMLAttributes attributes,
 596     Augmentations augs)throws XNIException {
 597 
 598         boolean requiredToken=false;
 599         if(fCurrentTokenType == 0)
 600             getNextToken();
 601         if(fCurrentTokenType ==1)
 602             requiredToken = checkIntegerToken(element);
 603         else if (fCurrentTokenType ==2)
 604             requiredToken = checkStringToken(element, attributes);
 605         if(requiredToken && hasMoreToken())
 606             getNextToken();
 607         if(fDocumentHandler != null && includeElement){
 608             elemCount++;
 609             fDocumentHandler.startElement(element, attributes, augs);
 610         }
 611 
 612     }
 613 
 614 
 615     public void endElement(QName element, Augmentations augs)
 616     throws XNIException {
 617         if(includeElement && foundElement != null ){
 618             if(elemCount >0 )elemCount --;
 619             fDocumentHandler.endElement(element, augs);
 620             if(elemCount == 0)includeElement = false;
 621 
 622         }else if(!ftempCurrentElement.empty()){
 623             QName name = (QName)ftempCurrentElement.peek();
 624             if(name.equals(element)){
 625                 ftempCurrentElement.pop();
 626                 skip = false;
 627             }
 628         }
 629     }
 630 
 631     public void emptyElement(QName element, XMLAttributes attributes,
 632     Augmentations augs)throws XNIException {
 633         if(fDocumentHandler != null && includeElement){
 634             fDocumentHandler.emptyElement(element, attributes, augs);
 635         }
 636     }
 637 
 638     public void startGeneralEntity(String name, XMLResourceIdentifier resId,
 639     String encoding,
 640     Augmentations augs)
 641     throws XNIException {
 642         if (fDocumentHandler != null && includeElement) {
 643             fDocumentHandler.startGeneralEntity(name, resId, encoding, augs);
 644         }
 645     }
 646 
 647     public void textDecl(String version, String encoding, Augmentations augs)
 648     throws XNIException {
 649         if (fDocumentHandler != null && includeElement) {
 650             fDocumentHandler.textDecl(version, encoding, augs);
 651         }
 652     }
 653 
 654     public void endGeneralEntity(String name, Augmentations augs)
 655     throws XNIException {
 656         if (fDocumentHandler != null) {
 657             fDocumentHandler.endGeneralEntity(name, augs);
 658         }
 659     }
 660 
 661     public void characters(XMLString text, Augmentations augs)
 662     throws XNIException {
 663         if (fDocumentHandler != null  && includeElement) {
 664             fDocumentHandler.characters(text, augs);
 665         }
 666     }
 667 
 668     public void ignorableWhitespace(XMLString text, Augmentations augs)
 669     throws XNIException {
 670         if (fDocumentHandler != null && includeElement) {
 671             fDocumentHandler.ignorableWhitespace(text, augs);
 672         }
 673     }
 674 
 675     public void startCDATA(Augmentations augs) throws XNIException {
 676         if (fDocumentHandler != null && includeElement) {
 677             fDocumentHandler.startCDATA(augs);
 678         }
 679     }
 680 
 681     public void endCDATA(Augmentations augs) throws XNIException {
 682         if (fDocumentHandler != null && includeElement) {
 683             fDocumentHandler.endCDATA(augs);
 684         }
 685     }
 686 
 687     public void endDocument(Augmentations augs) throws XNIException {
 688     }
 689 
 690     public void setDocumentSource(XMLDocumentSource source) {
 691         fDocumentSource = source;
 692     }
 693 
 694     public XMLDocumentSource getDocumentSource() {
 695         return fDocumentSource;
 696     }
 697 
 698 
 699     protected void reportFatalError(String key) {
 700         this.reportFatalError(key, null);
 701     }
 702 
 703     protected void reportFatalError(String key, Object[] args) {
 704         if (fErrorReporter != null) {
 705             fErrorReporter.reportError(
 706             fDocLocation,
 707             XIncludeMessageFormatter.XINCLUDE_DOMAIN,
 708             key,
 709             args,
 710             XMLErrorReporter.SEVERITY_FATAL_ERROR);
 711         }
 712         // we won't worry about when error reporter is null, since there should always be
 713         // at least the default error reporter
 714     }
 715 
 716 
 717 
 718     // used to know whether to pass declarations to the document handler
 719     protected boolean isRootDocument() {
 720         return this.fParentXIncludeHandler == null;
 721     }
 722 
 723 
 724 } // class XPointerElementhandler