Package net.sourceforge.marathon.runtime

Source Code of net.sourceforge.marathon.runtime.JavaRuntimeLeash$StdErr

/*******************************************************************************
*  Copyright (C) 2010 Jalian Systems Private Ltd.
*  Copyright (C) 2010 Contributors to Marathon OSS Project
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Library General Public
*  License as published by the Free Software Foundation; either
*  version 2 of the License, or (at your option) any later version.
*
*  This library 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
*  Library General Public License for more details.
*
*  You should have received a copy of the GNU Library General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*  Project website: http://www.marathontesting.com
*  Help: Marathon help forum @ http://groups.google.com/group/marathon-testing
*
*******************************************************************************/
package net.sourceforge.marathon.runtime;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Logger;

import net.sourceforge.marathon.Constants;
import net.sourceforge.marathon.api.IConsole;
import net.sourceforge.marathon.api.IJavaRuntimeInstantiator;
import net.sourceforge.marathon.api.ILogger;
import net.sourceforge.marathon.api.IMarathonRuntime;
import net.sourceforge.marathon.api.IRecorder;
import net.sourceforge.marathon.api.IScript;
import net.sourceforge.marathon.api.MarathonRuntimeException;
import net.sourceforge.marathon.api.WindowId;
import net.sourceforge.marathon.api.module.Module;
import net.sourceforge.marathon.util.ConsoleWriter;
import net.sourceforge.marathon.util.Retry;
import net.sourceforge.marathon.util.StreamPumper;
import net.sourceforge.rmilite.Client;
import net.sourceforge.rmilite.RemoteInvocationException;

/**
* JavaRuntimeLeash is just a wrapper around a remote java runtime running
* inside another process. It handles the interface to the remote process,
* redirecting the output of its std in and std out, as well as arbitrating
* communication with this process.
*
* This decorate JavaRuntime which is a proxy for JavaRuntimeLauncher
*/
public class JavaRuntimeLeash implements IMarathonRuntime {

    private static Logger logger = Logger.getLogger(JavaRuntimeLeash.class.getName());

    private static class StdOut extends ConsoleWriter {
        public StdOut(final IConsole console) {
            super(new Writer() {
                public void write(char cbuf[], int off, int len) throws IOException {
                    console.writeStdOut(cbuf, off, len);
                }

                public void flush() throws IOException {
                }

                public void close() throws IOException {
                }
            });
        }
    }

    private static class StdErr extends ConsoleWriter {
        public StdErr(final IConsole console) {
            super(new Writer() {
                public void write(char cbuf[], int off, int len) throws IOException {
                    console.writeStdErr(cbuf, off, len);
                }

                public void flush() throws IOException {
                }

                public void close() throws IOException {
                }
            });
        }
    }

    private IMarathonRuntime impl;
    private StdOut stdout;
    private StdErr stderr;
    private IJavaRuntimeInstantiator instantiator;
    private Thread shThread;

    public JavaRuntimeLeash(Client client, Process process, IConsole console, ILogger logViewLogger) {
        stdout = new StdOut(console);
        stderr = new StdErr(console);
        redirectOutput(process.getInputStream(), stdout);
        redirectOutput(process.getErrorStream(), stderr);
        addShutdownHook();
        getInstantiator(client);
        try {
            impl = instantiator.createRuntime(console, logViewLogger);
        } catch (RuntimeException e) {
            throw e;
        }
    }

    public IScript createScript(String content, String filename, boolean isDebugging) {
        return createScript(content, filename, false, isDebugging);
    }

    public IScript createScript(String content, String filename, boolean isRecording, boolean isDebugging) {
        return impl.createScript(content, filename, isRecording, isDebugging);
    }

    public void startRecording(IRecorder recorder) {
        impl.startRecording(recorder);
    }

    public void stopRecording() {
        try {
            impl.stopRecording();
        } catch (RemoteInvocationException e) {
            throw new MarathonRuntimeException();
        }
    }

    public void destroy() {
        flush();
        logger.info("Destroying the VM");
        try {
            impl.aboutToDestroy();
        } catch (Throwable t) {
        }
        try {
            impl.destroy();
        } catch (Throwable t) {
        }
        if (shThread != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(shThread);
            } catch (IllegalStateException e) {
            }
        }
    }

    private void flush() {
        try {
            stdout.flush();
            stderr.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void redirectOutput(InputStream inputStream, Writer writer) {
        new StreamPumper(inputStream, writer).start();
    }

    /**
     * don't let these bad boys hang around after this vm shuts down.
     */
    private void addShutdownHook() {
        shThread = new Thread() {
            public void run() {
                logger.info("Destroying the VM");
                JavaRuntimeLeash.this.destroy();
            }
        };
        Runtime.getRuntime().addShutdownHook(shThread);
    }

    private void getInstantiator(final Client client) {
        final Exception[] passback = new Exception[1];
        try {
            new Retry("looking up runtime instantiator", 600, 100, new Retry.Attempt() {
                public void perform() {
                    try {
                        instantiator = (IJavaRuntimeInstantiator) client.lookup(IJavaRuntimeInstantiator.class);
                        instantiator.setProperties(getProperties());
                        passback[0] = null;// clear the exception
                    } catch (Exception e) {
                        passback[0] = e;
                        retry();
                    }
                }

                private Properties getProperties() {
                    Properties props = System.getProperties();
                    Properties vmProps = new Properties();
                    Set<Object> keys = props.keySet();
                    for (Iterator<Object> iter = keys.iterator(); iter.hasNext();) {
                        String key = (String) iter.next();
                        if (key.startsWith(Constants.PROP_PROPPREFIX)) {
                            vmProps.put(key.substring(Constants.PROP_PROPPREFIX.length()), props.getProperty(key));
                        } else if (key.startsWith("marathon")) {
                            vmProps.put(key, props.getProperty(key));
                        }
                    }
                    return vmProps;
                }
            });
        } finally {
            // ensure the last exception gets printed if we failed
            if (passback[0] != null) {
                System.err.println("Error in JavaRuntimeLeash");
                passback[0].printStackTrace();
            }
        }
    }

    public void startApplication() {
        impl.startApplication();
    }

    public void stopApplication() {
        impl.stopApplication();
    }

    public Module getModuleFunctions() {
        return impl.getModuleFunctions();
    }

    public void exec(String function) {
        impl.exec(function);
    }

    public void setRawRecording(boolean selected) {
        impl.setRawRecording(selected);
    }

    public String evaluate(String code) {
        return impl.evaluate(code);
    }

    public WindowId getTopWindowId() {
        return impl.getTopWindowId();
    }

    public File getScreenCapture() {
        return impl.getScreenCapture();
    }

    public boolean isCustomAssertionsAvailable() {
        return impl.isCustomAssertionsAvailable();
    }

    public String[][] getCustomAssertions(Object mcomponent) {
        return impl.getCustomAssertions(mcomponent);
    }

    public void insertScript(String function) {
        impl.insertScript(function);
    }

    public void aboutToDestroy() {
        // TODO Auto-generated method stub

    }
}
TOP

Related Classes of net.sourceforge.marathon.runtime.JavaRuntimeLeash$StdErr

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.