Package com.meterware.httpunit.parsing

Source Code of com.meterware.httpunit.parsing.NekoDOMParser

package com.meterware.httpunit.parsing;

import com.meterware.httpunit.scripting.ScriptableDelegate;

import java.net.URL;
import java.io.IOException;
import java.util.Enumeration;

import org.cyberneko.html.HTMLConfiguration;
import org.apache.xerces.xni.parser.XMLDocumentFilter;
import org.apache.xerces.xni.parser.XMLErrorHandler;
import org.apache.xerces.xni.parser.XMLParseException;
import org.apache.xerces.xni.XNIException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.w3c.dom.Node;
import org.w3c.dom.Document;

/**
*
*
* @author <a href="russgold@acm.org">Russell Gold</a>
* @author <a href="mailto:Artashes.Aghajanyan@lycos-europe.com">Artashes Aghajanyan</a>
**/
class NekoDOMParser extends org.apache.xerces.parsers.DOMParser {

    private static final String HTML_DOCUMENT_CLASS_NAME = "org.apache.html.dom.HTMLDocumentImpl";

    /** Error reporting feature identifier. */
    private static final String REPORT_ERRORS = "http://cyberneko.org/html/features/report-errors";

    /** Augmentations feature identifier. */
    private static final String AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";

    /** Filters property identifier. */
    private static final String FILTERS = "http://cyberneko.org/html/properties/filters";

    /** Element case settings. possible values: "upper", "lower", "match" */
    private static final String TAG_NAME_CASE = "http://cyberneko.org/html/properties/names/elems";

    /** Attribute case settings. possible values: "upper", "lower", "no-change" */
    private static final String ATTRIBUTE_NAME_CASE = "http://cyberneko.org/html/properties/names/attrs";

    private DocumentAdapter _documentAdapter;

    /** The node representing the document. **/
    private Node _documentNode;


    static NekoDOMParser newParser( DocumentAdapter adapter, URL url ) {
        final HTMLConfiguration configuration = new HTMLConfiguration();
        if (!HTMLParserFactory.getHTMLParserListeners().isEmpty() || HTMLParserFactory.isParserWarningsEnabled()) {
            configuration.setErrorHandler( new ErrorHandler( url ) );
            configuration.setFeature( REPORT_ERRORS, true);
        }
        configuration.setFeature( AUGMENTATIONS, true );
        final ScriptFilter javaScriptFilter = new ScriptFilter( configuration );
        configuration.setProperty( FILTERS, new XMLDocumentFilter[] { javaScriptFilter } );
        if (HTMLParserFactory.isPreserveTagCase()) {
            configuration.setProperty( TAG_NAME_CASE, "match" );
            configuration.setProperty( ATTRIBUTE_NAME_CASE, "no-change" );
        }

        try {
            final NekoDOMParser domParser = new NekoDOMParser( configuration, adapter );
            domParser.setFeature( DEFER_NODE_EXPANSION, false );
            if (HTMLParserFactory.isReturnHTMLDocument()) domParser.setProperty( DOCUMENT_CLASS_NAME, HTML_DOCUMENT_CLASS_NAME );
            javaScriptFilter.setParser( domParser );
            return domParser;
        } catch (SAXNotRecognizedException e) {
            throw new RuntimeException( e.toString() );
        } catch (SAXNotSupportedException e) {
            throw new RuntimeException( e.toString() );
        }

    }


    ScriptableDelegate getScriptableDelegate() {
        if (_documentNode == null) {
            Node node = getCurrentElementNode();
            while (!(node instanceof Document)) node = node.getParentNode();
            _documentNode = node;
        }
        _documentAdapter.setRootNode( _documentNode );
        return _documentAdapter.getScriptableObject();
    }


    private Node getCurrentElementNode() {
        try {
            final Node node = (Node) getProperty( CURRENT_ELEMENT_NODE );
            return node;
        } catch (SAXNotRecognizedException e) {
            throw new RuntimeException( CURRENT_ELEMENT_NODE + " property not recognized" );
        } catch (SAXNotSupportedException e) {
            e.printStackTrace();
            throw new RuntimeException( CURRENT_ELEMENT_NODE + " property not supported" );
        }
    }


    String getIncludedScript( String srcAttribute ) {
        try {
            return _documentAdapter.getIncludedScript( srcAttribute );
        } catch (IOException e) {
            throw new ScriptException( e );
        }
    }


    NekoDOMParser( HTMLConfiguration configuration, DocumentAdapter adapter ) {
        super( configuration );
        _documentAdapter = adapter;
    }


    static class ScriptException extends RuntimeException {
        private IOException _cause;

        public ScriptException( IOException cause ) {
            _cause = cause;
        }

        public IOException getException() {
            return _cause;
        }
    }
}


class ErrorHandler implements XMLErrorHandler {

    private URL _url = null;

    ErrorHandler( URL url ) {
        _url = url;
    }

    public void warning( String domain, String key, XMLParseException warningException ) throws XNIException {
        if (HTMLParserFactory.isParserWarningsEnabled()) {
            System.out.println( "At line " + warningException.getLineNumber() + ", column " + warningException.getColumnNumber() + ": " + warningException.getMessage() );
        }

        Enumeration enum = HTMLParserFactory.getHTMLParserListeners().elements();
        while (enum.hasMoreElements()) {
            ((HTMLParserListener) enum.nextElement()).warning( _url, warningException.getMessage(), warningException.getLineNumber(), warningException.getColumnNumber() );
        }
    }


    public void error( String domain, String key, XMLParseException errorException ) throws XNIException {
        Enumeration enum = HTMLParserFactory.getHTMLParserListeners().elements();
        while (enum.hasMoreElements()) {
            ((HTMLParserListener) enum.nextElement()).error( _url, errorException.getMessage(), errorException.getLineNumber(), errorException.getColumnNumber() );
        }
    }


    public void fatalError( String domain, String key, XMLParseException fatalError ) throws XNIException {
        error( domain, key, fatalError );
        throw fatalError;
    }
}
TOP

Related Classes of com.meterware.httpunit.parsing.NekoDOMParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.