FileDocCategorySizeDatePackage
ElementSchemePointer.javaAPI DocApache Xerces 3.0.131749Fri Sep 14 20:33:52 BST 2007org.apache.xerces.xpointer

ElementSchemePointer

public class ElementSchemePointer extends Object implements XPointerPart

Implements the XPointerPart interface for element() scheme specific processing.

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

Fields Summary
private String
fSchemeName
private String
fSchemeData
private String
fShortHandPointerName
private boolean
fIsResolveElement
private boolean
fIsElementFound
private boolean
fWasOnlyEmptyElementFound
boolean
fIsShortHand
int
fFoundDepth
private int[]
fChildSequence
private int
fCurrentChildPosition
private int
fCurrentChildDepth
private int[]
fCurrentChildSequence
private boolean
fIsFragmentResolved
private ShortHandPointer
fShortHandPointer
protected org.apache.xerces.impl.XMLErrorReporter
fErrorReporter
protected org.apache.xerces.xni.parser.XMLErrorHandler
fErrorHandler
private org.apache.xerces.util.SymbolTable
fSymbolTable
Constructors Summary
public ElementSchemePointer()


    // ************************************************************************
    // Constructors
    // ************************************************************************
      
    
public ElementSchemePointer(org.apache.xerces.util.SymbolTable symbolTable)

        fSymbolTable = symbolTable;
    
public ElementSchemePointer(org.apache.xerces.util.SymbolTable symbolTable, org.apache.xerces.impl.XMLErrorReporter errorReporter)

        fSymbolTable = symbolTable;
        fErrorReporter = errorReporter;
    
Methods Summary
protected booleancheckMatch()
Matches the current position of the element being visited by checking its position and previous elements against the element XPointer expression. If a match is found it return true else false.

return
boolean

        // If the number of elements in the ChildSequence is greater than the
        // current child depth, there is not point in checking further
        if (!fIsShortHand) {
            // If a shorthand pointer is not present traverse the children
            // and compare
            if (fChildSequence.length <= fCurrentChildDepth + 1) {

                for (int i = 0; i < fChildSequence.length; i++) {
                    if (fChildSequence[i] != fCurrentChildSequence[i]) {
                        return false;
                    }
                }
            } else {
                return false;
            }
        } else {
            // If a shorthand pointer is present traverse the children
            // ignoring the first element of the CurrenChildSequence which
            // contains the ShortHand pointer element and compare            
            if (fChildSequence.length <= fCurrentChildDepth + 1) {

                for (int i = 0; i < fChildSequence.length; i++) {
                    // ensure fCurrentChildSequence is large enough
                    if (fCurrentChildSequence.length < i + 2) {
                        return false;
                    }

                    // ignore the first element of fCurrentChildSequence
                    if (fChildSequence[i] != fCurrentChildSequence[i + 1]) {
                        return false;
                    }
                }
            } else {
                return false;
            }

        }

        return true;
    
public java.lang.StringgetSchemeData()
Returns the scheme data

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

        return fSchemeData;
    
public java.lang.StringgetSchemeName()
Returns the scheme name i.e element

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

        return fSchemeName;
    
protected voidinit()
Initializes the element scheme processor

        fSchemeName = null;
        fSchemeData = null;
        fShortHandPointerName = null;
        fIsResolveElement = false;
        fIsElementFound = false;
        fWasOnlyEmptyElementFound = false;
        fFoundDepth = 0;
        fCurrentChildPosition = 1;
        fCurrentChildDepth = 0;
        fIsFragmentResolved = false;
        fShortHandPointer = null;
        
        initErrorReporter();
    
protected voidinitErrorReporter()
Initializes error handling objects

        if (fErrorReporter == null) {
            fErrorReporter = new XMLErrorReporter();
        }
        if (fErrorHandler == null) {
            fErrorHandler = new XPointerErrorHandler();
        }
        fErrorReporter.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()

    	// if only a shorthand pointer was present
    	if (fIsShortHand && fShortHandPointer != null && fChildSequence.length <= 0) {
    		return fShortHandPointer.isChildFragmentResolved();
    	} else {
    		return fWasOnlyEmptyElementFound ? !fWasOnlyEmptyElementFound
    				: (fIsFragmentResolved && (fCurrentChildDepth >= fFoundDepth));
    	}
    
public booleanisFragmentResolved()
Returns true if the node matches or is a child of a matching element() scheme XPointer.

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

        // Return true if the Fragment was resolved and the current Node depth
        // is greater than or equal to the depth at which the element was found
        return fIsFragmentResolved ;
    
protected booleanmatchChildSequence(org.apache.xerces.xni.QName element, int event)
Matches the current element position in the document tree with the element position specified in the element XPointer scheme.

param
event
return
boolean - true if the current element position in the document tree matches theelement position specified in the element XPointer scheme.

    	
        // need to resize fCurrentChildSequence
        if (fCurrentChildDepth >= fCurrentChildSequence.length) {
            int tmpCurrentChildSequence[] = new int[fCurrentChildSequence.length];
            System.arraycopy(fCurrentChildSequence, 0, tmpCurrentChildSequence,
                    0, fCurrentChildSequence.length);

            // Increase the size by a factor of 2 (?)
            fCurrentChildSequence = new int[fCurrentChildDepth * 2];
            System.arraycopy(tmpCurrentChildSequence, 0, fCurrentChildSequence,
                    0, tmpCurrentChildSequence.length);
        }

        //     
        if (fIsResolveElement) {
            // start
            if (event == XPointerPart.EVENT_ELEMENT_START) {
                fCurrentChildSequence[fCurrentChildDepth] = fCurrentChildPosition;
                fCurrentChildDepth++;

                // reset the current child position 
                fCurrentChildPosition = 1;

                //if (!fSchemeNameFound) {
                if ((fCurrentChildDepth <= fFoundDepth) || (fFoundDepth == 0)) {
                    if (checkMatch()) {
                        fIsElementFound = true;
                        fFoundDepth = fCurrentChildDepth;
                    } else {
                        fIsElementFound = false;
                        fFoundDepth = 0;
                    }
                }

            } else if (event == XPointerPart.EVENT_ELEMENT_END) {
                if (fCurrentChildDepth == fFoundDepth) {
                    fIsElementFound = true;
                } else if (((fCurrentChildDepth < fFoundDepth) && (fFoundDepth != 0))
                        || ((fCurrentChildDepth > fFoundDepth) // or empty element found
                        && (fFoundDepth == 0))) {
                    fIsElementFound = false;
                }

                // reset array position of last child
                fCurrentChildSequence[fCurrentChildDepth] = 0;

                fCurrentChildDepth--;
                fCurrentChildPosition = fCurrentChildSequence[fCurrentChildDepth] + 1;
                
            } else if (event == XPointerPart.EVENT_ELEMENT_EMPTY) {

                fCurrentChildSequence[fCurrentChildDepth] = fCurrentChildPosition;
                fCurrentChildPosition++;

                // Donot check for empty elements if the empty element is 
                // a child of a found parent element 
                if (checkMatch()) {
                    if (!fIsElementFound) {
                        fWasOnlyEmptyElementFound = true;
                    } else {
                        fWasOnlyEmptyElementFound = false;
                    }
                    fIsElementFound = true;
                } else {
                    fIsElementFound = false;
                    fWasOnlyEmptyElementFound = false;
                }  
            }
        }

        return fIsElementFound;
    
public voidparseXPointer(java.lang.String xpointer)
Parses the XPointer expression and tokenizes it into Strings delimited by whitespace.

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


        //
        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_ELEM_CHILD
                        || token == Tokens.XPTRTOKEN_ELEM_NCNAME) {
                    super.addToken(tokens, token);
                    return;
                }
                reportError("InvalidElementSchemeToken", new Object[] { tokens
                        .getTokenString(token) });
            }
        };

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

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

        // Initialize a temp arrays to the size of token count which should 
        // be atleast twice the size of child sequence, to hold the ChildSequence.
        int tmpChildSequence[] = new int[tokens.getTokenCount() / 2 + 1];

        // the element depth          
        int i = 0;

        // Traverse the scanned tokens
        while (tokens.hasMore()) {
            int token = tokens.nextToken();

            switch (token) {
            case Tokens.XPTRTOKEN_ELEM_NCNAME: {
                // Note:  Only a single ShortHand pointer can be present

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

                // Create a new ShortHandPointer
                fShortHandPointer = new ShortHandPointer(fSymbolTable);
                fShortHandPointer.setSchemeName(fShortHandPointerName);

                break;
            }
            case Tokens.XPTRTOKEN_ELEM_CHILD: {
                tmpChildSequence[i] = tokens.nextToken();
                i++;

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

        // Initialize the arrays to the number of elements in the ChildSequence.
        fChildSequence = new int[i];
        fCurrentChildSequence = new int[i];
        System.arraycopy(tmpChildSequence, 0, fChildSequence, 0, i);

    
protected voidreportError(java.lang.String key, java.lang.Object[] arguments)
Reports an XPointer error

    	/*fErrorReporter.reportError(XPointerMessageFormatter.XPOINTER_DOMAIN,
    	 key, arguments, XMLErrorReporter.SEVERITY_ERROR);
    	 */        
    	throw new XNIException((fErrorReporter
    			.getMessageFormatter(XPointerMessageFormatter.XPOINTER_DOMAIN))
				.formatMessage(fErrorReporter.getLocale(), key, arguments));
    
public booleanresolveXPointer(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs, int event)
Responsible for resolving the element() scheme XPointer. If a ShortHand Pointer is present and it is successfully resolved and if a child sequence is present, the child sequence is resolved relative to it.

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 isShortHandPointerResolved = false;

        // if a ChildSequence exisits, resolve child elements

        // if an element name exists
        if (fShortHandPointerName != null) {
            // resolve ShortHand Pointer
            isShortHandPointerResolved = fShortHandPointer.resolveXPointer(
                    element, attributes, augs, event);
            if (isShortHandPointerResolved) {
                fIsResolveElement = true;
                fIsShortHand = true;
            } else {
                fIsResolveElement = false;
            }
        } else {
            fIsResolveElement = true;
        }

        // Added here to skip the ShortHand pointer corresponding to
        // an element if one exisits and start searching from its child
        if (fChildSequence.length > 0) {
            fIsFragmentResolved = matchChildSequence(element, event);
        } else if (isShortHandPointerResolved && fChildSequence.length <= 0) {
            // if only a resolved shorthand pointer exists
            fIsFragmentResolved = isShortHandPointerResolved;
        } else {
            fIsFragmentResolved = false;
        }

        return fIsFragmentResolved;
    
public voidsetSchemeData(java.lang.String schemeData)
Sets the scheme data

see
org.apache.xerces.xpointer.XPointerPart#setSchemeData(java.lang.String)

        fSchemeData = schemeData;
    
public voidsetSchemeName(java.lang.String schemeName)
Sets the scheme name

see
org.apache.xerces.xpointer.XPointerPart#setSchemeName(java.lang.String)

        fSchemeName = schemeName;