All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.hudson.impl.HudsonFailureDataProvider Maven / Gradle / Ivy

There is a newer version: RELEASE240
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.hudson.impl;

import java.awt.Toolkit;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.hudson.api.ConnectionBuilder;
import org.netbeans.modules.hudson.api.HudsonJob;
import org.netbeans.modules.hudson.api.HudsonJobBuild;
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer;
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer.Case;
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer.Suite;
import org.netbeans.modules.hudson.spi.BuilderConnector;
import org.openide.awt.StatusDisplayer;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.xml.XMLUtil;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author jhavlin
 */
@NbBundle.Messages({
    "no_test_result=No test result found for this build."})
public class HudsonFailureDataProvider extends BuilderConnector.FailureDataProvider {

    private static final Logger LOG = Logger.getLogger(
            HudsonFailureDataProvider.class.getName());

    @Override
    public void showFailures(final HudsonJobBuild build,
            final FailureDataDisplayer displayer) {
        new RequestProcessor(build.getUrl() + "failures").post( // NOI18N
                new Runnable() {
            @Override
            public void run() {
                showBuildFailures(build.getJob(), build.getUrl(), displayer);
            }
        });
    }

    @Override
    public void showFailures(final HudsonMavenModuleBuild moduleBuild,
            final FailureDataDisplayer displayer) {
        new RequestProcessor(moduleBuild.getUrl() + "failures").post( // NOI18N
                new Runnable() {
            @Override
            public void run() {
                showBuildFailures(moduleBuild.getBuild().getJob(),
                        moduleBuild.getUrl(), displayer);
            }
        });
    }

    private void showBuildFailures(HudsonJob job, String url,
            FailureDataDisplayer displayer) {

        try {
            XMLReader parser = XMLUtil.createXMLReader();
            parser.setContentHandler(new ContentHandler(displayer));
            // XXX could use ?tree (would be faster) if there were an alternate object for failed tests only
            String u = url + "testReport/api/xml?xpath=//suite[case/errorStackTrace]&wrapper=failures"; //NOI18N
            InputSource source = new InputSource(new ConnectionBuilder().job(job).url(u).connection().getInputStream());
            source.setSystemId(u);
            displayer.open();
            parser.parse(source);
        } catch (FileNotFoundException x) {
            Toolkit.getDefaultToolkit().beep();
            StatusDisplayer.getDefault().setStatusText(Bundle.no_test_result());
        } catch (Exception x) {
            Toolkit.getDefaultToolkit().beep();
            LOG.log(Level.INFO, null, x);
        }
    }

    private class ContentHandler extends DefaultHandler {

        private StringBuilder buf;
        private final FailureDataDisplayer displayer;

        public ContentHandler(FailureDataDisplayer displayer) {
            this.displayer = displayer;
        }

        long parseDuration(String d) {
            if (d == null) {
                return 0;
            }
            try {
                return (long) (1000 * Float.parseFloat(d));
            } catch (NumberFormatException x) {
                return 0;
            }
        }

        Suite suite = null;
        Case caze = null;

        public @Override
        void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if (qName.matches("errorStackTrace|stdout|stderr|name|className")) { //NOI18N
                buf = new StringBuilder();
            } else if (qName.equals("suite")) { //NOI18N
                suite = new Suite();
                caze = null;
            } else if (qName.equals("case") && suite != null) { //NOI18N
                caze = new Case();
            }
        }

        public @Override
        void characters(char[] ch, int start, int length) throws SAXException {
            if (buf != null) {
                buf.append(ch, start, length);
            }
        }

        public @Override
        void endElement(String uri, String localName, String qName) throws SAXException {
            if (suite == null) {
                return;
            }
            String text = buf != null && buf.length() > 0 ? buf.toString() : null;
            buf = null;
            if (caze == null) { // suite level
                if (qName.equals("stdout")) { // NOI18N
                    suite.setStdout(text);
                } else if (qName.equals("stderr")) { // NOI18N
                    suite.setStderr(text);
                } else if (qName.equals("name")) { // NOI18N
                    suite.setName(text);
                } else if (qName.equals("duration")) { // NOI18N
                    suite.setDuration(parseDuration(text));
                }
            } else { // case level
                if (qName.equals("errorStackTrace")) { // NOI18N
                    caze.setErrorStackTrace(text);
                } else if (qName.equals("name")) { // NOI18N
                    caze.setName(text);
                } else if (qName.equals("className")) { // NOI18N
                    caze.setClassName(text);
                } else if (qName.equals("duration")) { // NOI18N
                    caze.setDuration(parseDuration(text));
                }
            }
            if (qName.equals("case")) { //NOI18N
                suite.addCase(caze);
                caze = null;
            } else if (qName.equals("suite")) { // NOI18N
                try {
                    displayer.showSuite(suite);
                } catch (Exception x) {
                    LOG.log(Level.FINE, null, x);
                }
                suite = null;
            }
        }

        @Override
        public void endDocument() throws SAXException {
            displayer.close();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy