org.jboss.rusheye.parser.Parser.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.rusheye.parser.Parser.java

Source

/**
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.rusheye.parser;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.StreamFilter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.commons.io.FileUtils;
import org.codehaus.stax2.XMLInputFactory2;
import org.codehaus.stax2.XMLStreamReader2;
import org.codehaus.stax2.ri.Stax2FilteredStreamReader;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.XMLValidationSchemaFactory;
import org.jboss.rusheye.exception.ConfigurationException;
import org.jboss.rusheye.exception.ConfigurationValidationException;
import org.jboss.rusheye.exception.ParsingException;
import org.jboss.rusheye.listener.SuiteListenerAdapter;
import org.jboss.rusheye.listener.SuiteListener;
import org.jboss.rusheye.suite.GlobalConfiguration;
import org.jboss.rusheye.suite.Mask;
import org.jboss.rusheye.suite.Pattern;
import org.jboss.rusheye.suite.Properties;
import org.jboss.rusheye.suite.Test;
import org.jboss.rusheye.suite.VisualSuite;

import com.ctc.wstx.exc.WstxParsingException;
import com.ctc.wstx.exc.WstxValidationException;

/**
 * @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
 * @version $Revision$
 */
public final class Parser {

    private Set<SuiteListener> listeners = new LinkedHashSet<SuiteListener>();
    private Handler handler = new Handler(listeners);
    private Properties properties;

    public Parser() {
        this.registerListener(new ParserListenerRegistrationListener());
    }

    public void parseResource(String resourceName) {
        InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceName);
        parseStream(inputStream);
    }

    public void parseStream(InputStream inputStream) {
        try {
            File tmp = File.createTempFile(Parser.class.getName(), ".tmp");
            BufferedInputStream in = new BufferedInputStream(inputStream);
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tmp));

            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.close();
            in.close();
            parseFileTempFile(tmp);
        } catch (IOException e) {
            throw new ParsingException(e);
        }
    }

    public void parseFile(File file) {
        parseFile(file, false);
    }

    public void parseFileTempFile(File file) {
        parseFile(file, true);
    }

    private void parseFile(File file, boolean tmpfile) {
        VisualSuite visualSuite = null;
        try {
            XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory
                    .newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
            URL schemaURL = getClass().getClassLoader().getResource("org/jboss/rusheye/visual-suite.xsd");
            XMLValidationSchema schema = schemaFactory.createSchema(schemaURL);

            XMLInputFactory2 factory = (XMLInputFactory2) XMLInputFactory.newInstance();

            StreamFilter filter = new StreamFilter() {
                @Override
                public boolean accept(XMLStreamReader reader) {
                    return reader.isStartElement();
                }
            };

            XMLStreamReader2 reader = factory.createXMLStreamReader(file);
            XMLStreamReader2 filteredReader = new Stax2FilteredStreamReader(reader, filter);

            reader.validateAgainst(schema);

            // EventFilter filter = new EventFilter() {
            // @Override
            // public boolean accept(XMLEvent reader) {
            // return reader.isStartElement();
            // }
            // };
            //
            // XMLEventReader reader = factory.createXMLEventReader(file);
            // XMLEventReader filteredReader = factory.createFilteredReader(reader, filter);

            JAXBContext ctx = JAXBContext.newInstance(VisualSuite.class.getPackage().getName());
            Unmarshaller um = ctx.createUnmarshaller();

            UnmarshallerMultiListener listener = new UnmarshallerMultiListener();
            um.setListener(listener);

            // skip parsing of the first element - visual-suite
            filteredReader.nextTag();

            visualSuite = new VisualSuite();
            handler.setVisualSuite(visualSuite);
            handler.getContext().invokeListeners().onSuiteStarted(visualSuite);

            listener.registerListener(new UniqueIdentityChecker(handler.getContext()));

            while (filteredReader.hasNext()) {
                try {
                    // go on the start of the next tag
                    filteredReader.nextTag();

                    Object o = um.unmarshal(reader);
                    if (o instanceof GlobalConfiguration) {
                        GlobalConfiguration globalConfiguration = (GlobalConfiguration) o;
                        handler.getContext().setCurrentConfiguration(globalConfiguration);
                        visualSuite.setGlobalConfiguration(globalConfiguration);
                        handler.getContext().invokeListeners().onConfigurationReady(visualSuite);

                        RetriverInjector retriverInjector = new RetriverInjector(this);
                        for (Mask mask : globalConfiguration.getMasks()) {
                            retriverInjector.afterUnmarshal(mask, null);
                        }
                        listener.registerListener(retriverInjector);
                    }
                    if (o instanceof Test) {
                        Test test = (Test) o;
                        handler.getContext().setCurrentConfiguration(test);
                        handler.getContext().setCurrentTest(test);
                        for (Pattern pattern : test.getPatterns()) {
                            handler.getContext().invokeListeners().onPatternReady(test, pattern);
                        }
                        Test testWrapped = ConfigurationCompiler.wrap(test, visualSuite.getGlobalConfiguration());
                        handler.getContext().invokeListeners().onTestReady(testWrapped);
                    }
                } catch (WstxParsingException e) {
                    // intentionally blank - wrong end of document detection
                }

            }
        } catch (XMLStreamException e) {
            throw handleParsingException(e, e);
        } catch (JAXBException e) {
            throw handleParsingException(e, e.getLinkedException());
        } finally {
            if (visualSuite != null && handler.getContext() != null) {
                handler.getContext().invokeListeners().onSuiteReady(visualSuite);
            }
            if (tmpfile) {
                FileUtils.deleteQuietly(file);
            }
        }
    }

    private RuntimeException handleParsingException(Throwable originalException, Throwable cause) {
        if (cause != null && cause instanceof WstxValidationException) {
            String message = cause.getMessage().replaceAll("\n", "");
            return new ConfigurationValidationException(message, cause);
        }
        return new ParsingException(originalException);
    }

    public void registerListener(SuiteListener parserListener) {
        synchronized (parserListener) {
            if (listeners.contains(parserListener)) {
                return;
            }
            listeners.add(parserListener);
        }
    }

    public void unregisterListener(SuiteListener parserListener) {
        synchronized (listeners) {
            if (listeners.contains(parserListener)) {
                listeners.remove(parserListener);
            }
        }
        throw new IllegalStateException("Given parser isn't registered");
    }

    Handler getHandler() {
        return handler;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    private class ParserListenerRegistrationListener extends SuiteListenerAdapter {
        @Override
        public void onConfigurationReady(VisualSuite visualSuite) {
            for (SuiteListener listener : visualSuite.getGlobalConfiguration().getListeners()) {
                if (Parser.this.properties != null) {
                    listener.setProperties(Parser.this.properties);
                }
                listener.onSuiteStarted(visualSuite);
                listener.onConfigurationReady(visualSuite);
                Parser.this.registerListener(listener);
            }

            if (listeners.size() == 1) {
                throw new ConfigurationException("No ParserListener was registered to process parsed tests");
            }
        }
    }
}