src/com/sun/org/apache/xerces/internal/xpointer/XPointerHandler.java

Print this page


   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 package com.sun.org.apache.xerces.internal.xpointer;
  21 
  22 import java.util.Hashtable;
  23 import java.util.Vector;
  24 
  25 import com.sun.org.apache.xerces.internal.impl.Constants;
  26 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  27 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  28 import com.sun.org.apache.xerces.internal.util.XMLChar;
  29 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  30 import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
  31 import com.sun.org.apache.xerces.internal.xinclude.XIncludeNamespaceSupport;
  32 import com.sun.org.apache.xerces.internal.xni.Augmentations;
  33 import com.sun.org.apache.xerces.internal.xni.QName;
  34 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;

  35 import com.sun.org.apache.xerces.internal.xni.XMLString;
  36 import com.sun.org.apache.xerces.internal.xni.XNIException;
  37 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  38 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  39 
  40 /**
  41  * <p>
  42  * This is a pipeline component which extends the XIncludeHandler to perform
  43  * XPointer specific processing specified in the W3C XPointerFramework and
  44  * element() Scheme Recommendations.
  45  * </p>
  46  *
  47  * <p>
  48  * This component analyzes each event in the pipeline, looking for an element
  49  * that matches a PointerPart in the parent XInclude element's xpointer attribute
  50  * value.  If the match succeeds, all children are passed by this component.
  51  * </p>
  52  *
  53  * <p>
  54  * See the <a href="http://www.w3.org/TR/xptr-framework//">XPointer Framework Recommendation</a> for
  55  * more information on the XPointer Framework and ShortHand Pointers.
  56  * See the <a href="http://www.w3.org/TR/xptr-element/">XPointer element() Scheme Recommendation</a> for
  57  * more information on the XPointer element() Scheme.
  58  * </p>
  59  *
  60  * @xerces.internal
  61  *
  62  */
  63 public final class XPointerHandler extends XIncludeHandler implements
  64         XPointerProcessor {
  65 
  66     // Fields
  67     // A Vector of XPointerParts
  68     protected Vector fXPointerParts = null;
  69 
  70     // The current XPointerPart
  71     protected XPointerPart fXPointerPart = null;
  72 
  73     // Has the fXPointerPart resolved successfully
  74     protected boolean fFoundMatchingPtrPart = false;
  75 
  76     // The XPointer Error reporter
  77     protected XMLErrorReporter fXPointerErrorReporter;
  78 
  79     // The XPointer Error Handler
  80     protected XMLErrorHandler fErrorHandler;
  81 
  82     // XPointerFramework symbol table
  83     protected SymbolTable fSymbolTable = null;
  84 
  85     // Supported schemes
  86     private final String ELEMENT_SCHEME_NAME = "element";
  87 
  88    // Has the XPointer resolved the subresource
  89     protected boolean fIsXPointerResolved = false;
  90 
  91     // Fixup xml:base and xml:lang attributes
  92     protected boolean fFixupBase = false;
  93     protected boolean fFixupLang = false;
  94 
  95     // ************************************************************************
  96     // Constructors
  97     // ************************************************************************
  98 
  99     /**
 100      *
 101      */
 102     public XPointerHandler() {
 103         super();
 104 
 105         fXPointerParts = new Vector();
 106         fSymbolTable = new SymbolTable();
 107     }
 108 
 109     public XPointerHandler(SymbolTable symbolTable,
 110             XMLErrorHandler errorHandler, XMLErrorReporter errorReporter) {
 111         super();
 112 
 113         fXPointerParts = new Vector();
 114         fSymbolTable = symbolTable;
 115         fErrorHandler = errorHandler;
 116         fXPointerErrorReporter = errorReporter;
 117         //fErrorReporter = errorReporter; // The XInclude ErrorReporter
 118     }
 119 




 120     // ************************************************************************
 121     //  Implementation of the XPointerProcessor interface.
 122     // ************************************************************************
 123 
 124     /**
 125      * Parses the XPointer framework expression and delegates scheme specific parsing.
 126      *
 127      * @see com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor#parseXPointer(java.lang.String)
 128      */
 129     public void parseXPointer(String xpointer) throws XNIException {
 130 
 131         // Initialize
 132         init();
 133 
 134         // tokens
 135         final Tokens tokens = new Tokens(fSymbolTable);
 136 
 137         // scanner
 138         Scanner scanner = new Scanner(fSymbolTable) {
 139             protected void addToken(Tokens tokens, int token)


 283      *
 284      * @see com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor#resolveXPointer(com.sun.org.apache.xerces.internal.xni.QName, com.sun.org.apache.xerces.internal.xni.XMLAttributes, com.sun.org.apache.xerces.internal.xni.Augmentations, int event)
 285      */
 286     public boolean resolveXPointer(QName element, XMLAttributes attributes,
 287             Augmentations augs, int event) throws XNIException {
 288         boolean resolved = false;
 289 
 290         // The result of the first pointer part whose evaluation identifies
 291         // one or more subresources is reported by the XPointer processor as the
 292         // result of the pointer as a whole, and evaluation stops.
 293         // In our implementation, typically the first xpointer scheme that
 294         // matches an element is the document is considered.
 295         // If the pointer part resolved then use it, else search for the fragment
 296         // using next pointer part from lef-right.
 297         if (!fFoundMatchingPtrPart) {
 298 
 299             // for each element, attempt to resolve it against each pointer part
 300             // in the XPointer expression until a matching element is found.
 301             for (int i = 0; i < fXPointerParts.size(); i++) {
 302 
 303                 fXPointerPart = (XPointerPart) fXPointerParts.get(i);
 304 
 305                 if (fXPointerPart.resolveXPointer(element, attributes, augs,
 306                         event)) {
 307                     fFoundMatchingPtrPart = true;
 308                     resolved = true;
 309                 }
 310             }
 311         } else {
 312             if (fXPointerPart.resolveXPointer(element, attributes, augs, event)) {
 313                 resolved = true;
 314             }
 315         }
 316 
 317         if (!fIsXPointerResolved) {
 318             fIsXPointerResolved = resolved;
 319         }
 320 
 321         return resolved;
 322     }
 323 


 413         fXPointerErrorReporter.putMessageFormatter(
 414                 XPointerMessageFormatter.XPOINTER_DOMAIN,
 415                 new XPointerMessageFormatter());
 416     }
 417 
 418     /**
 419      * Initializes the XPointer Processor;
 420      */
 421     protected void init() {
 422         fXPointerParts.clear();
 423         fXPointerPart = null;
 424         fFoundMatchingPtrPart = false;
 425         fIsXPointerResolved = false;
 426         //fFixupBase = false;
 427         //fFixupLang = false;
 428 
 429         initErrorReporter();
 430     }
 431 
 432     /**
 433      * Returns a Vector of XPointerPart objects
 434      *
 435      * @return A Vector of XPointerPart objects.
 436      */
 437     public Vector getPointerParts() {
 438         return fXPointerParts;
 439     }
 440 
 441     /**
 442      * List of XPointer Framework tokens.
 443      *
 444      * @xerces.internal
 445      *
 446      */
 447     private final class Tokens {
 448 
 449         /**
 450          * XPointer Framework tokens
 451          * [1] Pointer     ::= Shorthand | SchemeBased
 452          * [2] Shorthand   ::= NCName
 453          * [3] SchemeBased ::= PointerPart (S? PointerPart)*
 454          * [4] PointerPart ::= SchemeName '(' SchemeData ')'
 455          * [5] SchemeName  ::= QName
 456          * [6] SchemeData  ::= EscapedData*
 457          * [7] EscapedData ::= NormalChar | '^(' | '^)' | '^^' | '(' SchemeData ')'


 463                 XPTRTOKEN_CLOSE_PAREN = 1, XPTRTOKEN_SHORTHAND = 2,
 464                 XPTRTOKEN_SCHEMENAME = 3, XPTRTOKEN_SCHEMEDATA = 4;
 465 
 466         // Token names
 467         private final String[] fgTokenNames = { "XPTRTOKEN_OPEN_PAREN",
 468                 "XPTRTOKEN_CLOSE_PAREN", "XPTRTOKEN_SHORTHAND",
 469                 "XPTRTOKEN_SCHEMENAME", "XPTRTOKEN_SCHEMEDATA" };
 470 
 471         // Token count
 472         private static final int INITIAL_TOKEN_COUNT = 1 << 8;
 473 
 474         private int[] fTokens = new int[INITIAL_TOKEN_COUNT];
 475 
 476         private int fTokenCount = 0;
 477 
 478         // Current token position
 479         private int fCurrentTokenIndex;
 480 
 481         private SymbolTable fSymbolTable;
 482 
 483         private Hashtable fTokenNames = new Hashtable();
 484 
 485         /**
 486          * Constructor
 487          *
 488          * @param symbolTable SymbolTable
 489          */
 490         private Tokens(SymbolTable symbolTable) {
 491             fSymbolTable = symbolTable;
 492 
 493             fTokenNames.put(new Integer(XPTRTOKEN_OPEN_PAREN),
 494                     "XPTRTOKEN_OPEN_PAREN");
 495             fTokenNames.put(new Integer(XPTRTOKEN_CLOSE_PAREN),
 496                     "XPTRTOKEN_CLOSE_PAREN");
 497             fTokenNames.put(new Integer(XPTRTOKEN_SHORTHAND),
 498                     "XPTRTOKEN_SHORTHAND");
 499             fTokenNames.put(new Integer(XPTRTOKEN_SCHEMENAME),
 500                     "XPTRTOKEN_SCHEMENAME");
 501             fTokenNames.put(new Integer(XPTRTOKEN_SCHEMEDATA),
 502                     "XPTRTOKEN_SCHEMEDATA");
 503         }
 504 
 505         /**
 506          * Returns the token String
 507          * @param token The index of the token
 508          * @return String The token string
 509          */
 510         private String getTokenString(int token) {
 511             return (String) fTokenNames.get(new Integer(token));
 512         }
 513 
 514         /**
 515          * Add the specified string as a token
 516          *
 517          * @param token The token string
 518          */
 519         private void addToken(String tokenStr) {
 520             Integer tokenInt = (Integer) fTokenNames.get(tokenStr);
 521             if (tokenInt == null) {
 522                 tokenInt = new Integer(fTokenNames.size());
 523                 fTokenNames.put(tokenInt, tokenStr);
 524             }
 525             addToken(tokenInt.intValue());

 526         }
 527 
 528         /**
 529          * Add the specified int token
 530          *
 531          * @param token The int specifying the token
 532          */
 533         private void addToken(int token) {
 534             try {
 535                 fTokens[fTokenCount] = token;
 536             } catch (ArrayIndexOutOfBoundsException ex) {
 537                 int[] oldList = fTokens;
 538                 fTokens = new int[fTokenCount << 1];
 539                 System.arraycopy(oldList, 0, fTokens, 0, fTokenCount);
 540                 fTokens[fTokenCount] = token;
 541             }
 542             fTokenCount++;
 543         }
 544 
 545         /**


   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.xpointer;
  23 
  24 import java.util.ArrayList;
  25 import java.util.HashMap;
  26 
  27 import com.sun.org.apache.xerces.internal.impl.Constants;
  28 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  29 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  30 import com.sun.org.apache.xerces.internal.util.XMLChar;
  31 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  32 import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler;
  33 import com.sun.org.apache.xerces.internal.xinclude.XIncludeNamespaceSupport;
  34 import com.sun.org.apache.xerces.internal.xni.Augmentations;
  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.XMLString;
  39 import com.sun.org.apache.xerces.internal.xni.XNIException;
  40 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  41 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  42 
  43 /**
  44  * <p>
  45  * This is a pipeline component which extends the XIncludeHandler to perform
  46  * XPointer specific processing specified in the W3C XPointerFramework and
  47  * element() Scheme Recommendations.
  48  * </p>
  49  *
  50  * <p>
  51  * This component analyzes each event in the pipeline, looking for an element
  52  * that matches a PointerPart in the parent XInclude element's xpointer attribute
  53  * value.  If the match succeeds, all children are passed by this component.
  54  * </p>
  55  *
  56  * <p>
  57  * See the <a href="http://www.w3.org/TR/xptr-framework//">XPointer Framework Recommendation</a> for
  58  * more information on the XPointer Framework and ShortHand Pointers.
  59  * See the <a href="http://www.w3.org/TR/xptr-element/">XPointer element() Scheme Recommendation</a> for
  60  * more information on the XPointer element() Scheme.
  61  * </p>
  62  *
  63  * @xerces.internal
  64  *
  65  */
  66 public final class XPointerHandler extends XIncludeHandler implements
  67         XPointerProcessor {
  68 
  69     // Fields
  70     // An ArrayList of XPointerParts
  71     protected ArrayList<XPointerPart> fXPointerParts = null;
  72 
  73     // The current XPointerPart
  74     protected XPointerPart fXPointerPart = null;
  75 
  76     // Has the fXPointerPart resolved successfully
  77     protected boolean fFoundMatchingPtrPart = false;
  78 
  79     // The XPointer Error reporter
  80     protected XMLErrorReporter fXPointerErrorReporter;
  81 
  82     // The XPointer Error Handler
  83     protected XMLErrorHandler fErrorHandler;
  84 
  85     // XPointerFramework symbol table
  86     protected SymbolTable fSymbolTable = null;
  87 
  88     // Supported schemes
  89     private final String ELEMENT_SCHEME_NAME = "element";
  90 
  91    // Has the XPointer resolved the subresource
  92     protected boolean fIsXPointerResolved = false;
  93 
  94     // Fixup xml:base and xml:lang attributes
  95     protected boolean fFixupBase = false;
  96     protected boolean fFixupLang = false;
  97 
  98     // ************************************************************************
  99     // Constructors
 100     // ************************************************************************
 101 
 102     /**
 103      *
 104      */
 105     public XPointerHandler() {
 106         super();
 107 
 108         fXPointerParts = new ArrayList<>();
 109         fSymbolTable = new SymbolTable();
 110     }
 111 
 112     public XPointerHandler(SymbolTable symbolTable,
 113             XMLErrorHandler errorHandler, XMLErrorReporter errorReporter) {
 114         super();
 115 
 116         fXPointerParts = new ArrayList<>();
 117         fSymbolTable = symbolTable;
 118         fErrorHandler = errorHandler;
 119         fXPointerErrorReporter = errorReporter;
 120         //fErrorReporter = errorReporter; // The XInclude ErrorReporter
 121     }
 122 
 123     public void setDocumentHandler(XMLDocumentHandler handler) {
 124         fDocumentHandler = handler;
 125     }
 126     
 127     // ************************************************************************
 128     //  Implementation of the XPointerProcessor interface.
 129     // ************************************************************************
 130 
 131     /**
 132      * Parses the XPointer framework expression and delegates scheme specific parsing.
 133      *
 134      * @see com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor#parseXPointer(java.lang.String)
 135      */
 136     public void parseXPointer(String xpointer) throws XNIException {
 137 
 138         // Initialize
 139         init();
 140 
 141         // tokens
 142         final Tokens tokens = new Tokens(fSymbolTable);
 143 
 144         // scanner
 145         Scanner scanner = new Scanner(fSymbolTable) {
 146             protected void addToken(Tokens tokens, int token)


 290      *
 291      * @see com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor#resolveXPointer(com.sun.org.apache.xerces.internal.xni.QName, com.sun.org.apache.xerces.internal.xni.XMLAttributes, com.sun.org.apache.xerces.internal.xni.Augmentations, int event)
 292      */
 293     public boolean resolveXPointer(QName element, XMLAttributes attributes,
 294             Augmentations augs, int event) throws XNIException {
 295         boolean resolved = false;
 296 
 297         // The result of the first pointer part whose evaluation identifies
 298         // one or more subresources is reported by the XPointer processor as the
 299         // result of the pointer as a whole, and evaluation stops.
 300         // In our implementation, typically the first xpointer scheme that
 301         // matches an element is the document is considered.
 302         // If the pointer part resolved then use it, else search for the fragment
 303         // using next pointer part from lef-right.
 304         if (!fFoundMatchingPtrPart) {
 305 
 306             // for each element, attempt to resolve it against each pointer part
 307             // in the XPointer expression until a matching element is found.
 308             for (int i = 0; i < fXPointerParts.size(); i++) {
 309 
 310                 fXPointerPart = fXPointerParts.get(i);
 311 
 312                 if (fXPointerPart.resolveXPointer(element, attributes, augs,
 313                         event)) {
 314                     fFoundMatchingPtrPart = true;
 315                     resolved = true;
 316                 }
 317             }
 318         } else {
 319             if (fXPointerPart.resolveXPointer(element, attributes, augs, event)) {
 320                 resolved = true;
 321             }
 322         }
 323 
 324         if (!fIsXPointerResolved) {
 325             fIsXPointerResolved = resolved;
 326         }
 327 
 328         return resolved;
 329     }
 330 


 420         fXPointerErrorReporter.putMessageFormatter(
 421                 XPointerMessageFormatter.XPOINTER_DOMAIN,
 422                 new XPointerMessageFormatter());
 423     }
 424 
 425     /**
 426      * Initializes the XPointer Processor;
 427      */
 428     protected void init() {
 429         fXPointerParts.clear();
 430         fXPointerPart = null;
 431         fFoundMatchingPtrPart = false;
 432         fIsXPointerResolved = false;
 433         //fFixupBase = false;
 434         //fFixupLang = false;
 435 
 436         initErrorReporter();
 437     }
 438 
 439     /**
 440      * Returns an ArrayList of XPointerPart objects
 441      *
 442      * @return An ArrayList of XPointerPart objects.
 443      */
 444     public ArrayList<XPointerPart> getPointerParts() {
 445         return fXPointerParts;
 446     }
 447 
 448     /**
 449      * List of XPointer Framework tokens.
 450      *
 451      * @xerces.internal
 452      *
 453      */
 454     private final class Tokens {
 455 
 456         /**
 457          * XPointer Framework tokens
 458          * [1] Pointer     ::= Shorthand | SchemeBased
 459          * [2] Shorthand   ::= NCName
 460          * [3] SchemeBased ::= PointerPart (S? PointerPart)*
 461          * [4] PointerPart ::= SchemeName '(' SchemeData ')'
 462          * [5] SchemeName  ::= QName
 463          * [6] SchemeData  ::= EscapedData*
 464          * [7] EscapedData ::= NormalChar | '^(' | '^)' | '^^' | '(' SchemeData ')'


 470                 XPTRTOKEN_CLOSE_PAREN = 1, XPTRTOKEN_SHORTHAND = 2,
 471                 XPTRTOKEN_SCHEMENAME = 3, XPTRTOKEN_SCHEMEDATA = 4;
 472 
 473         // Token names
 474         private final String[] fgTokenNames = { "XPTRTOKEN_OPEN_PAREN",
 475                 "XPTRTOKEN_CLOSE_PAREN", "XPTRTOKEN_SHORTHAND",
 476                 "XPTRTOKEN_SCHEMENAME", "XPTRTOKEN_SCHEMEDATA" };
 477 
 478         // Token count
 479         private static final int INITIAL_TOKEN_COUNT = 1 << 8;
 480 
 481         private int[] fTokens = new int[INITIAL_TOKEN_COUNT];
 482 
 483         private int fTokenCount = 0;
 484 
 485         // Current token position
 486         private int fCurrentTokenIndex;
 487 
 488         private SymbolTable fSymbolTable;
 489 
 490         private HashMap<Integer, String> fTokenNames = new HashMap<>();
 491 
 492         /**
 493          * Constructor
 494          *
 495          * @param symbolTable SymbolTable
 496          */
 497         private Tokens(SymbolTable symbolTable) {
 498             fSymbolTable = symbolTable;
 499 
 500             fTokenNames.put(new Integer(XPTRTOKEN_OPEN_PAREN),
 501                     "XPTRTOKEN_OPEN_PAREN");
 502             fTokenNames.put(new Integer(XPTRTOKEN_CLOSE_PAREN),
 503                     "XPTRTOKEN_CLOSE_PAREN");
 504             fTokenNames.put(new Integer(XPTRTOKEN_SHORTHAND),
 505                     "XPTRTOKEN_SHORTHAND");
 506             fTokenNames.put(new Integer(XPTRTOKEN_SCHEMENAME),
 507                     "XPTRTOKEN_SCHEMENAME");
 508             fTokenNames.put(new Integer(XPTRTOKEN_SCHEMEDATA),
 509                     "XPTRTOKEN_SCHEMEDATA");
 510         }
 511 
 512         /**
 513          * Returns the token String
 514          * @param token The index of the token
 515          * @return String The token string
 516          */
 517         private String getTokenString(int token) {
 518             return fTokenNames.get(new Integer(token));
 519         }
 520 
 521         /**
 522          * Add the specified string as a token
 523          *
 524          * @param token The token string
 525          */
 526         private void addToken(String tokenStr) {
 527             if (!fTokenNames.containsValue(tokenStr)) {
 528                 Integer tokenInt = new Integer(fTokenNames.size());

 529                 fTokenNames.put(tokenInt, tokenStr);

 530                 addToken(tokenInt.intValue());
 531             }
 532         }
 533 
 534         /**
 535          * Add the specified int token
 536          *
 537          * @param token The int specifying the token
 538          */
 539         private void addToken(int token) {
 540             try {
 541                 fTokens[fTokenCount] = token;
 542             } catch (ArrayIndexOutOfBoundsException ex) {
 543                 int[] oldList = fTokens;
 544                 fTokens = new int[fTokenCount << 1];
 545                 System.arraycopy(oldList, 0, fTokens, 0, fTokenCount);
 546                 fTokens[fTokenCount] = token;
 547             }
 548             fTokenCount++;
 549         }
 550 
 551         /**