Package org.apache.tapestry.test

Source Code of org.apache.tapestry.test.IntegrationTestScriptParser

// Copyright 2004, 2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.tapestry.test;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Resource;
import org.apache.hivemind.parse.AbstractParser;
import org.apache.hivemind.parse.ElementParseInfo;
import org.apache.tapestry.test.assertions.AssertOutput;
import org.apache.tapestry.test.assertions.AssertRegexp;
import org.apache.tapestry.test.assertions.RegexpMatch;
import org.apache.tapestry.util.xml.DocumentParseException;

/**
* Parses Tapestry test scripts; XML files that define an execution environment and
* a sequence of operations and assertions.
*
* @author Howard Lewis Ship
* @since 4.0
*/
public class IntegrationTestScriptParser extends AbstractParser
{
    private ScriptDescriptor _scriptDescriptor;
    private Map _attributes;
    private String _elementName;

    /**
     * Map from element name to a ElementParseInfo
     */
    private final Map _elementParseInfo = new HashMap();

    public IntegrationTestScriptParser()
    {
        initializeFromPropertiesFile();
    }

    private void initializeFromPropertiesFile()
    {
        Properties p = new Properties();
        InputStream stream = null;

        try
        {

            InputStream rawStream = getClass().getResourceAsStream("ScriptParser.properties");
            stream = new BufferedInputStream(rawStream);

            p.load(stream);

            stream.close();
            stream = null;
        }
        catch (IOException ex)
        {
            throw new ApplicationRuntimeException(ex);
        }
        finally
        {
            close(stream);
        }

        initializeFromProperties(p);
    }

    private void initializeFromProperties(Properties p)
    {
        Iterator i = p.keySet().iterator();
        while (i.hasNext())
        {
            String key = (String) i.next();
            String value = p.getProperty(key);

            initializeFromProperty(key, value);
        }
    }

    private void initializeFromProperty(String key, String value)
    {
        // Ignore keys that don't start with "required."

        if (!key.startsWith("required."))
            return;

        int lastDotx = key.lastIndexOf('.');

        String elementName = key.substring(9, lastDotx);
        String attributeName = key.substring(lastDotx + 1);

        boolean required = value.equalsIgnoreCase("true");

        ElementParseInfo epi = getElementParseInfo(elementName);

        epi.addAttribute(attributeName, required);
    }

    private void close(InputStream stream)
    {
        try
        {
            if (stream != null)
                stream.close();
        }
        catch (IOException ex)
        {
            // Ingore.
        }
    }

    public ScriptDescriptor parse(Resource script)
    {
        initializeParser(script, STATE_INITIAL);

        try
        {
            startParse();

            return _scriptDescriptor;
        }
        finally
        {
            resetParser();
        }
    }

    private void startParse()
    {
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();

            SAXParser parser = factory.newSAXParser();

            Resource resource = getResource();

            URL url = resource.getResourceURL();

            InputStream is = url.openStream();

            parser.parse(is, this);
        }
        catch (Exception ex)
        {
            throw new DocumentParseException(ex.getMessage(), getResource(), ex);
        }
    }

    protected void initializeParser(Resource resource, int startState)
    {
        super.initializeParser(resource, startState);

        _attributes = new HashMap();
    }

    protected void resetParser()
    {
        _attributes = null;
        _elementName = null;
        _scriptDescriptor = null;

        super.resetParser();
    }

    private static final int STATE_INITIAL = 0;
    private static final int STATE_TEST_SCRIPT = 1;
    private static final int STATE_SERVLET = 2;
    private static final int STATE_INIT_PARAMETER = 3;
    private static final int STATE_REQUEST = 4;
    private static final int STATE_ASSERT_OUTPUT = 5;
    private static final int STATE_ASSERT_REGEXP = 6;
    private static final int STATE_MATCH = 7;

    private static final int STATE_NO_CONTENT = 1000;

    protected void begin(String elementName, Map attributes)
    {
        _elementName = elementName;
        _attributes = attributes;

        switch (getState())
        {
            case STATE_INITIAL :
                beginInitial();
                break;

            case STATE_TEST_SCRIPT :
                beginTestScript();
                break;

            case STATE_SERVLET :
                beginServlet();
                break;

            case STATE_REQUEST :
                beginRequest();
                break;

            case STATE_ASSERT_REGEXP :
                beginAssertRegexp();
                break;

            default :
                unexpectedElement(_elementName);
        }
    }

    protected void end(String elementName)
    {
        _elementName = elementName;

        switch (getState())
        {
            case STATE_ASSERT_OUTPUT :

                endAssertOutput();
                break;

            case STATE_ASSERT_REGEXP :
                endAssertRegexp();
                break;

            case STATE_MATCH :
                endMatch();
                break;

            default :
                break;
        }

        pop();

    }

    private void beginInitial()
    {
        if (_elementName.equals("test-script"))
        {
            enterTestScript();
            return;
        }

        unexpectedElement(_elementName);
    }

    private void beginTestScript()
    {
        if (_elementName.equals("servlet"))
        {
            enterServlet();
            return;
        }

        if (_elementName.equals("request"))
        {
            enterRequest();
            return;
        }

        unexpectedElement(_elementName);
    }

    private void beginServlet()
    {
        if (_elementName.equals("init-parameter"))
        {
            enterInitParameter();
            return;
        }

        unexpectedElement(_elementName);
    }

    private void enterRequest()
    {
        validateAttributes();

        String servletName = getAttribute("servlet");
        String servletPath = getAttribute("servlet-path", "/app");

        RequestDescriptor rd = new RequestDescriptor();
        rd.setServletName(servletName);
        rd.setServletPath(servletPath);

        ScriptDescriptor sd = (ScriptDescriptor) peekObject();

        sd.addRequestDescriptor(rd);

        push(_elementName, rd, STATE_REQUEST);
    }

    public void beginRequest()
    {
        if (_elementName.equals("parameter"))
        {
            enterParameter();
            return;
        }

        if (_elementName.equals("assert-output"))
        {
            enterAssertOutput();
            return;
        }

        if (_elementName.equals("assert-regexp"))
        {
            enterAssertRegexp();
            return;
        }

        unexpectedElement(_elementName);
    }

    private void enterAssertOutput()
    {
        validateAttributes();

        AssertOutput ao = new AssertOutput();
        RequestDescriptor rd = (RequestDescriptor) peekObject();

        rd.addAssertion(ao);

        push(_elementName, ao, STATE_ASSERT_OUTPUT, false);
    }

    private void enterAssertRegexp()
    {
        validateAttributes();

        int subgroup = getIntAttribute("subgroup", 0);

        AssertRegexp ar = new AssertRegexp();
        ar.setSubgroup(subgroup);

        RequestDescriptor rd = (RequestDescriptor) peekObject();

        rd.addAssertion(ar);

        push(_elementName, ar, STATE_ASSERT_REGEXP, false);
    }

    private void beginAssertRegexp()
    {
        if (_elementName.equals("match"))
        {
            enterMatch();
            return;
        }

        unexpectedElement(_elementName);
    }

    private void enterMatch()
    {
        validateAttributes();

        RegexpMatch m = new RegexpMatch();
        AssertRegexp ar = (AssertRegexp) peekObject();

        ar.addMatch(m);

        push(_elementName, m, STATE_MATCH, false);
    }

    private void endAssertOutput()
    {
        String content = peekContent();
        AssertOutput ao = (AssertOutput) peekObject();

        ao.setExpectedSubstring(content);
    }

    private void endAssertRegexp()
    {
        String content = peekContent();

        AssertRegexp ar = (AssertRegexp) peekObject();

        ar.setRegexp(content);
    }

    private void endMatch()
    {
        String content = peekContent();

        RegexpMatch m = (RegexpMatch) peekObject();

        m.setExpectedString(content);
    }

    protected String peekContent()
    {
        String rawContent = super.peekContent();

        if (rawContent == null)
            return null;

        return rawContent.trim();
    }

    private void enterParameter()
    {
        validateAttributes();

        String name = getAttribute("name");
        String value = getAttribute("value");

        RequestDescriptor rd = (RequestDescriptor) peekObject();

        rd.addParameter(name, value);

        push(_elementName, null, STATE_NO_CONTENT);
    }

    private void enterInitParameter()
    {
        validateAttributes();

        String name = getAttribute("name");
        String value = getAttribute("value");

        ServletDescriptor sd = (ServletDescriptor) peekObject();

        sd.addInitParameter(name, value);

        push(_elementName, null, STATE_NO_CONTENT);
    }

    private void enterTestScript()
    {
        validateAttributes();

        String contextName = getAttribute("context");
        String directory = getAttribute("directory");

        ScriptDescriptor sd = new ScriptDescriptor();
        sd.setContextName(contextName);
        sd.setRootDirectory(directory);

        _scriptDescriptor = sd;

        push(_elementName, sd, STATE_TEST_SCRIPT);
    }

    private void enterServlet()
    {
        validateAttributes();

        String name = getAttribute("name");
        String className = getAttribute("class", "org.apache.tapestry.ApplicationServlet");

        ServletDescriptor sd = new ServletDescriptor();
        sd.setName(name);
        sd.setClassName(className);

        // Can't wait for push() to do this, because of checks inside
        // addServletDescriptor().
        sd.setLocation(getLocation());

        ScriptDescriptor scriptDescriptor = (ScriptDescriptor) peekObject();

        scriptDescriptor.addServletDescriptor(sd);

        push(_elementName, sd, STATE_SERVLET);
    }

    private String getAttribute(String name)
    {
        return (String) _attributes.get(name);
    }

    private String getAttribute(String name, String defaultValue)
    {
        if (!_attributes.containsKey(name))
            return defaultValue;

        return (String) _attributes.get(name);
    }

    private void validateAttributes()
    {
        Iterator i = _attributes.keySet().iterator();

        ElementParseInfo epi = getElementParseInfo(_elementName);

        // First, check that each attribute is in the set of expected attributes.

        while (i.hasNext())
        {
            String name = (String) i.next();

            if (!epi.isKnown(name))
                throw new DocumentParseException(
                    ScriptMessages.unexpectedAttributeInElement(name, _elementName),
                    getLocation(),
                    null);
        }

        // Now check that all required attributes have been specified.

        i = epi.getRequiredNames();
        while (i.hasNext())
        {
            String name = (String) i.next();

            if (!_attributes.containsKey(name))
                throw new DocumentParseException(
                    ScriptMessages.missingRequiredAttribute(name, _elementName),
                    getLocation(),
                    null);
        }

    }

    private ElementParseInfo getElementParseInfo(String elementName)
    {
        ElementParseInfo result = (ElementParseInfo) _elementParseInfo.get(elementName);

        if (result == null)
        {
            result = new ElementParseInfo();
            _elementParseInfo.put(elementName, result);
        }

        return result;
    }

    private int getIntAttribute(String name, int defaultValue)
    {
        String attributeValue = getAttribute(name);

        if (attributeValue == null)
            return defaultValue;

        try
        {
            return Integer.parseInt(attributeValue);
        }
        catch (NumberFormatException ex)
        {
            throw new ApplicationRuntimeException(
                ScriptMessages.invalidIntAttribute(
                    name,
                    _elementName,
                    getLocation(),
                    attributeValue),
                getLocation(),
                ex);
        }
    }
}
TOP

Related Classes of org.apache.tapestry.test.IntegrationTestScriptParser

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.