FileDocCategorySizeDatePackage
XPointerHandler.javaAPI DocApache Xerces 3.0.148051Fri Sep 14 20:33:56 BST 2007org.apache.xerces.xpointer

XPointerHandler

public final class XPointerHandler extends org.apache.xerces.xinclude.XIncludeHandler implements XPointerProcessor

This is a pipeline component which extends the XIncludeHandler to perform XPointer specific processing specified in the W3C XPointerFramework and element() Scheme Recommendations.

This component analyzes each event in the pipeline, looking for an element that matches a PointerPart in the parent XInclude element's xpointer attribute value. If the match succeeds, all children are passed by this component.

See the XPointer Framework Recommendation for more information on the XPointer Framework and ShortHand Pointers. See the XPointer element() Scheme Recommendation for more information on the XPointer element() Scheme.

xerces.internal
version
$Id: XPointerHandler.java 447248 2006-09-18 05:25:21Z mrglavas $

Fields Summary
protected Vector
fXPointerParts
protected XPointerPart
fXPointerPart
protected boolean
fFoundMatchingPtrPart
protected org.apache.xerces.impl.XMLErrorReporter
fXPointerErrorReporter
protected org.apache.xerces.xni.parser.XMLErrorHandler
fErrorHandler
protected org.apache.xerces.util.SymbolTable
fSymbolTable
private final String
ELEMENT_SCHEME_NAME
protected boolean
fIsXPointerResolved
protected boolean
fFixupBase
protected boolean
fFixupLang
Constructors Summary
public XPointerHandler()

    
    // ************************************************************************
    // Constructors
    // ************************************************************************

           
      
        super();

        fXPointerParts = new Vector();
        fSymbolTable = new SymbolTable();
    
public XPointerHandler(org.apache.xerces.util.SymbolTable symbolTable, org.apache.xerces.xni.parser.XMLErrorHandler errorHandler, org.apache.xerces.impl.XMLErrorReporter errorReporter)

        super();

        fXPointerParts = new Vector();
        fSymbolTable = symbolTable;
        fErrorHandler = errorHandler;
        fXPointerErrorReporter = errorReporter;
        //fErrorReporter = errorReporter; // The XInclude ErrorReporter
    
Methods Summary
public voidcharacters(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
Character content.

param
text The content.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.characters(text, augs);
    
public voidcomment(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
If the comment is a child of a matched element, then pass else return.

param
text The text in the comment.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by application to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.comment(text, augs);
    
public voidemptyElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs)
An empty element.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!resolveXPointer(element, attributes, augs,
                XPointerPart.EVENT_ELEMENT_EMPTY)) {
            // xml:base and xml:lang processing
        	if (fFixupBase) {
                processXMLBaseAttributes(attributes);
        	}    
            if (fFixupLang) {
                processXMLLangAttributes(attributes);
            }
            // no need to restore restoreBaseURI() for xml:base and xml:lang processing
            
            // set the context invalid if the element till an element from the result infoset is included
            fNamespaceContext.setContextInvalid(); 
            return;
        }
        super.emptyElement(element, attributes, augs);
    
public voidendCDATA(org.apache.xerces.xni.Augmentations augs)
The end of a CDATA section.

param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.endCDATA(augs);
    
public voidendElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.Augmentations augs)
The end of an element.

param
element The name of the element.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!resolveXPointer(element, null, augs,
                XPointerPart.EVENT_ELEMENT_END)) {

            // no need to restore restoreBaseURI() for xml:base and xml:lang processing
            return;
        }
        super.endElement(element, augs);
    
public java.util.VectorgetPointerParts()
Returns a Vector of XPointerPart objects

return
A Vector of XPointerPart objects.

        return fXPointerParts;
    
public XPointerPartgetXPointerPart()
Returns the pointer part used to resolve the document fragment.

return
String - The pointer part used to resolve the document fragment.

        return fXPointerPart;
    
public voidignorableWhitespace(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
Ignorable whitespace. For this method to be called, the document source must have some way of determining that the text containing only whitespace characters should be considered ignorable. For example, the validator can determine if a length of whitespace characters in the document are ignorable based on the element content model.

param
text The ignorable whitespace.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.ignorableWhitespace(text, augs);
    
protected voidinit()
Initializes the XPointer Processor;

        fXPointerParts.clear();
        fXPointerPart = null;
        fFoundMatchingPtrPart = false;
        fIsXPointerResolved = false;
        //fFixupBase = false;
        //fFixupLang = false;

        initErrorReporter();
    
protected voidinitErrorReporter()
Initializes error handling objects

        if (fXPointerErrorReporter == null) {
            fXPointerErrorReporter = new XMLErrorReporter();
        }
        if (fErrorHandler == null) {
            fErrorHandler = new XPointerErrorHandler();
        }
        /*
         fXPointerErrorReporter.setProperty(Constants.XERCES_PROPERTY_PREFIX
         + Constants.ERROR_HANDLER_PROPERTY, fErrorHandler);
         */
        fXPointerErrorReporter.putMessageFormatter(
                XPointerMessageFormatter.XPOINTER_DOMAIN,
                new XPointerMessageFormatter());
    
public booleanisChildFragmentResolved()
Returns true if the XPointer expression resolves to a non-element child of the current resource fragment.

see
org.apache.xerces.xpointer.XPointerPart#isChildFragmentResolved()

    	boolean resolved = (fXPointerPart != null) ? fXPointerPart
				.isChildFragmentResolved() : false;
		return resolved;
    
public booleanisFragmentResolved()
Returns true if the Node fragment is resolved.

see
org.apache.xerces.xpointer.XPointerProcessor#isFragmentResolved()

        boolean resolved = (fXPointerPart != null) ? fXPointerPart.isFragmentResolved()
                : false;
        
        if (!fIsXPointerResolved) {
            fIsXPointerResolved = resolved;
        }
        
        return resolved;
    
public booleanisXPointerResolved()
Returns true if the XPointer successfully found a sub-resource .

see
org.apache.xerces.xpointer.XPointerProcessor#isFragmentResolved()

        return fIsXPointerResolved;
    
public voidparseXPointer(java.lang.String xpointer)
Parses the XPointer framework expression and delegates scheme specific parsing.

see
org.apache.xerces.xpointer.XPointerProcessor#parseXPointer(java.lang.String)


        // Initialize
        init();

        // tokens
        final Tokens tokens = new Tokens(fSymbolTable);

        // scanner
        Scanner scanner = new Scanner(fSymbolTable) {
            protected void addToken(Tokens tokens, int token)
                    throws XNIException {
                if (token == Tokens.XPTRTOKEN_OPEN_PAREN
                        || token == Tokens.XPTRTOKEN_CLOSE_PAREN
                        || token == Tokens.XPTRTOKEN_SCHEMENAME
                        || token == Tokens.XPTRTOKEN_SCHEMEDATA
                        || token == Tokens.XPTRTOKEN_SHORTHAND) {
                    super.addToken(tokens, token);
                    return;
                }
                reportError("InvalidXPointerToken", new Object[] { tokens
                        .getTokenString(token) });
            }
        };

        // scan the XPointer expression
        int length = xpointer.length();
        boolean success = scanner.scanExpr(fSymbolTable, tokens, xpointer, 0,
                length);

        if (!success)
            reportError("InvalidXPointerExpression", new Object[] { xpointer });

        while (tokens.hasMore()) {
            int token = tokens.nextToken();

            switch (token) {
            case Tokens.XPTRTOKEN_SHORTHAND: {

                // The shortHand name
                token = tokens.nextToken();
                String shortHandPointerName = tokens.getTokenString(token);

                if (shortHandPointerName == null) {
                    reportError("InvalidXPointerExpression",
                            new Object[] { xpointer });
                }

                XPointerPart shortHandPointer = new ShortHandPointer(
                        fSymbolTable);
                shortHandPointer.setSchemeName(shortHandPointerName);
                fXPointerParts.add(shortHandPointer);
                break;
            }
            case Tokens.XPTRTOKEN_SCHEMENAME: {

                // Retreive the local name and prefix to form the scheme name
                token = tokens.nextToken();
                String prefix = tokens.getTokenString(token);
                token = tokens.nextToken();
                String localName = tokens.getTokenString(token);

                String schemeName = prefix + localName;

                // The next character should be an open parenthesis
                int openParenCount = 0;
                int closeParenCount = 0;

                token = tokens.nextToken();
                String openParen = tokens.getTokenString(token);
                if (openParen != "XPTRTOKEN_OPEN_PAREN") {

                    // can not have more than one ShortHand Pointer
                    if (token == Tokens.XPTRTOKEN_SHORTHAND) {
                        reportError("MultipleShortHandPointers",
                                new Object[] { xpointer });
                    } else {
                        reportError("InvalidXPointerExpression",
                                new Object[] { xpointer });
                    }
                }
                openParenCount++;

                // followed by zero or more ( and  the schemeData
                String schemeData = null;
                while (tokens.hasMore()) {
                    token = tokens.nextToken();
                    schemeData = tokens.getTokenString(token);
                    if (schemeData != "XPTRTOKEN_OPEN_PAREN") {
                        break;
                    }
                    openParenCount++;
                }
                token = tokens.nextToken();
                schemeData = tokens.getTokenString(token);

                // followed by the same number of )
                token = tokens.nextToken();
                String closeParen = tokens.getTokenString(token);
                if (closeParen != "XPTRTOKEN_CLOSE_PAREN") {
                    reportError("SchemeDataNotFollowedByCloseParenthesis",
                            new Object[] { xpointer });
                }
                closeParenCount++;

                while (tokens.hasMore()) {
                    if (tokens.getTokenString(tokens.peekToken()) != "XPTRTOKEN_OPEN_PAREN") {
                        break;
                    }
                    closeParenCount++;
                }

                // check if the number of open parenthesis are equal to the number of close parenthesis
                if (openParenCount != closeParenCount) {
                    reportError("UnbalancedParenthesisInXPointerExpression",
                            new Object[] { xpointer,
                                    new Integer(openParenCount),
                                    new Integer(closeParenCount) });
                }

                // Perform scheme specific parsing of the pointer part
                if (schemeName.equals(ELEMENT_SCHEME_NAME)) {
                    XPointerPart elementSchemePointer = new ElementSchemePointer(
                            fSymbolTable, fErrorReporter);
                    elementSchemePointer.setSchemeName(schemeName);
                    elementSchemePointer.setSchemeData(schemeData);

                    // If an exception occurs while parsing the element() scheme expression
                    // ignore it and move on to the next pointer part
                    try {
                        elementSchemePointer.parseXPointer(schemeData);
                        fXPointerParts.add(elementSchemePointer);
                    } catch (XNIException e) {
                        // Re-throw the XPointer element() scheme syntax error.
                    	throw new XNIException (e);
                    }

                } else {
                    // ????
                    reportWarning("SchemeUnsupported",
                            new Object[] { schemeName });
                }

                break;
            }
            default:
                reportError("InvalidXPointerExpression",
                        new Object[] { xpointer });
            }
        }

    
public voidprocessingInstruction(java.lang.String target, org.apache.xerces.xni.XMLString data, org.apache.xerces.xni.Augmentations augs)
A processing instruction. Processing instructions consist of a target name and, optionally, text data. The data is only meaningful to the application.

Typically, a processing instruction's data will contain a series of pseudo-attributes. These pseudo-attributes follow the form of element attributes but are not parsed or presented to the application as anything other than text. The application is responsible for parsing the data.

param
target The target.
param
data The data or null if none specified.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.processingInstruction(target, data, augs);
    
private voidreportError(java.lang.String key, java.lang.Object[] arguments)
Reports XPointer Errors

        /* 
        fXPointerErrorReporter.reportError(
                XPointerMessageFormatter.XPOINTER_DOMAIN, key, arguments,
                XMLErrorReporter.SEVERITY_ERROR);
        */        
    	throw new XNIException((fErrorReporter
				.getMessageFormatter(XPointerMessageFormatter.XPOINTER_DOMAIN))
				.formatMessage(fErrorReporter.getLocale(), key, arguments));
    
private voidreportWarning(java.lang.String key, java.lang.Object[] arguments)
Reports XPointer Warnings

        fXPointerErrorReporter.reportError(
                XPointerMessageFormatter.XPOINTER_DOMAIN, key, arguments,
                XMLErrorReporter.SEVERITY_WARNING);
    
public booleanresolveXPointer(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs, int event)

see
org.apache.xerces.xpointer.XPointerProcessor#resolveXPointer(org.apache.xerces.xni.QName, org.apache.xerces.xni.XMLAttributes, org.apache.xerces.xni.Augmentations, int event)

    	boolean resolved = false;
    	
        // The result of the first pointer part whose evaluation identifies 
        // one or more subresources is reported by the XPointer processor as the 
        // result of the pointer as a whole, and evaluation stops.
        // In our implementation, typically the first xpointer scheme that 
        // matches an element is the document is considered.
        // If the pointer part resolved then use it, else search for the fragment
        // using next pointer part from lef-right.
        if (!fFoundMatchingPtrPart) {

            // for each element, attempt to resolve it against each pointer part 
            // in the XPointer expression until a matching element is found.
            for (int i = 0; i < fXPointerParts.size(); i++) {

                fXPointerPart = (XPointerPart) fXPointerParts.get(i);

                if (fXPointerPart.resolveXPointer(element, attributes, augs,
                        event)) {
                    fFoundMatchingPtrPart = true;
                    resolved = true;
                }
            }
        } else {
            if (fXPointerPart.resolveXPointer(element, attributes, augs, event)) {
            	resolved = true;
            }
        }

        if (!fIsXPointerResolved) {
            fIsXPointerResolved = resolved;
        }

        return resolved;
    
public voidsetDocumentHandler(org.apache.xerces.xni.XMLDocumentHandler handler)

        fDocumentHandler = handler;
    
public voidsetProperty(java.lang.String propertyId, java.lang.Object value)

Sets the value of a property. This method is called by the component manager any time after reset when a property changes value.

Note: Components should silently ignore properties that do not affect the operation of the component.

param
propertyId The property identifier.
param
value The value of the property.
throws
XMLConfigurationException Thrown for configuration error. In general, components should only throw this exception if it is really a critical error.


        // Error reporter
        if (propertyId == Constants.XERCES_PROPERTY_PREFIX
                + Constants.ERROR_REPORTER_PROPERTY) {
            if (value != null) {
                fXPointerErrorReporter = (XMLErrorReporter) value;
            } else {
                fXPointerErrorReporter = null;
            }
        }

        // Error handler
        if (propertyId == Constants.XERCES_PROPERTY_PREFIX
                + Constants.ERROR_HANDLER_PROPERTY) {
            if (value != null) {
                fErrorHandler = (XMLErrorHandler) value;
            } else {
                fErrorHandler = null;
            }
        }

        // xml:lang
        if (propertyId == Constants.XERCES_FEATURE_PREFIX
                + Constants.XINCLUDE_FIXUP_LANGUAGE_FEATURE) {
            if (value != null) {
            	fFixupLang = ((Boolean)value).booleanValue();
            } else {
            	fFixupLang = false;
            }
        }
        
        // xml:base
        if (propertyId == Constants.XERCES_FEATURE_PREFIX
                + Constants.XINCLUDE_FIXUP_BASE_URIS_FEATURE) {
            if (value != null) {
            	fFixupBase = ((Boolean)value).booleanValue();
            } else {
            	fFixupBase = false;
            }
        }
        
        // 
        if (propertyId == Constants.XERCES_PROPERTY_PREFIX
                + Constants.NAMESPACE_CONTEXT_PROPERTY) {
            fNamespaceContext = (XIncludeNamespaceSupport) value;
        }

        super.setProperty(propertyId, value);
    
public voidstartCDATA(org.apache.xerces.xni.Augmentations augs)
The start of a CDATA section.

param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!isChildFragmentResolved()) {
            return;
        }
        super.startCDATA(augs);
    
public voidstartElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs)
The start of an element.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (!resolveXPointer(element, attributes, augs,
                XPointerPart.EVENT_ELEMENT_START)) {

            // xml:base and xml:lang processing
        	if (fFixupBase) {
                processXMLBaseAttributes(attributes);
        	}
            if (fFixupLang) {
                processXMLLangAttributes(attributes);
            }

            // set the context invalid if the element till an element from the result infoset is included
            fNamespaceContext.setContextInvalid(); 

            return;
        }
        super.startElement(element, attributes, augs);