hudson.model.ExternalRun.java Source code

Java tutorial

Introduction

Here is the source code for hudson.model.ExternalRun.java

Source

/*******************************************************************************
 *
 * Copyright (c) 2004-2013 Oracle Corporation.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * 
 *    Kohsuke Kawaguchi, Roy Varghese
 *
 *
 *******************************************************************************/

package hudson.model;

import hudson.Proc;
import hudson.util.DecodingStream;
import hudson.util.DualOutputStream;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Reader;

import static javax.xml.stream.XMLStreamConstants.*;

/**
 * {@link Run} for {@link ExternalJob}.
 *
 * @author Kohsuke Kawaguchi
 */
public class ExternalRun extends Run<ExternalJob, ExternalRun> implements BuildNavigable {

    /**
     * Loads a run from a log file.
     */
    ExternalRun(ExternalJob owner, File runDir) throws IOException {
        super(owner, runDir);
    }

    /**
     * Creates a new run.
     */
    ExternalRun(ExternalJob project) throws IOException {
        super(project);
    }

    /**
     * Instead of performing a build, run the specified command, record the log
     * and its exit code, then call it a build.
     */
    public void run(final String[] cmd) {
        run(new Runner() {
            public Result run(BuildListener listener) throws Exception {
                Proc proc = new Proc.LocalProc(cmd, getEnvironment(listener), System.in,
                        new DualOutputStream(System.out, listener.getLogger()));
                return proc.join() == 0 ? Result.SUCCESS : Result.FAILURE;
            }

            public void post(BuildListener listener) {
                // do nothing
            }

            public void cleanUp(BuildListener listener) {
                // do nothing
            }
        });
    }

    /**
     * Instead of performing a build, accept the log and the return code from a
     * remote machine.
     *
     * <p> The format of the XML is:
     *
     * <pre><xmp>
     * <run>
     *  <log>...console output...</log>
     *  <result>exit code</result>
     * </run>
     * </xmp></pre>
     */
    @SuppressWarnings({ "Since15" })
    public void acceptRemoteSubmission(final Reader in) throws IOException {
        final long[] duration = new long[1];
        run(new Runner() {
            private String elementText(XMLStreamReader r) throws XMLStreamException {
                StringBuilder buf = new StringBuilder();
                while (true) {
                    int type = r.next();
                    if (type == CHARACTERS || type == CDATA) {
                        buf.append(r.getTextCharacters(), r.getTextStart(), r.getTextLength());
                    } else {
                        return buf.toString();
                    }
                }
            }

            public Result run(BuildListener listener) throws Exception {
                PrintStream logger = null;
                try {
                    logger = new PrintStream(new DecodingStream(listener.getLogger()));

                    XMLInputFactory xif = XMLInputFactory.newInstance();
                    XMLStreamReader p = xif.createXMLStreamReader(in);

                    p.nextTag(); // get to the <run>
                    p.nextTag(); // get to the <log>

                    charset = p.getAttributeValue(null, "content-encoding");
                    while (p.next() != END_ELEMENT) {
                        int type = p.getEventType();
                        if (type == CHARACTERS || type == CDATA) {
                            logger.print(p.getText());
                        }
                    }
                    p.nextTag(); // get to <result>

                    Result r = Integer.parseInt(elementText(p)) == 0 ? Result.SUCCESS : Result.FAILURE;

                    p.nextTag(); // get to <duration> (optional)
                    if (p.getEventType() == START_ELEMENT && p.getLocalName().equals("duration")) {
                        duration[0] = Long.parseLong(elementText(p));
                    }

                    return r;
                } finally {
                    IOUtils.closeQuietly(logger);
                }
            }

            public void post(BuildListener listener) {
                // do nothing
            }

            public void cleanUp(BuildListener listener) {
                // do nothing
            }
        });

        if (duration[0] != 0) {
            super.duration = duration[0];
            // save the updated duration
            save();
        }
    }

    @Override
    public BuildNavigator getBuildNavigator() {
        return null;
    }

    @Override
    public void setBuildNavigator(BuildNavigator buildNavigator) {
        // no-op. Let super classes take care of managing builds
        // for now.
    }
}