Package org.syrup.functions

Source Code of org.syrup.functions.BShell$BlobClientHandler

package org.syrup.functions;

import org.syrup.Context;
import org.syrup.Function;
import org.syrup.Result;
import org.syrup.helpers.DataImpl;
import org.syrup.helpers.ResultImpl;
import org.syrup.helpers.Utils;
import org.syrup.helpers.Writer;
import org.syrup.services.BlobClient;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;

import javax.naming.InitialContext;

/**
* Executes a shell command, provided by the first input, using a BlobServer.
* The second input provides the stdin. If the second input is not given the
* first (command) input is consumed. The first output maps to stdout and the
* second output to stderr. Only the second input and first output are put
* through a BlobServer. This makes the processing of big inputs and outputs
* possible without overloading the backing store implementation of Syrup.
*
* @author Robbert van Dalen
*/
public class BShell extends Thread implements Function
{
    static final String COPYRIGHT = "Copyright 2005 Robbert van Dalen."
        + "At your option, you may copy, distribute, or make derivative works under "
        + "the terms of The Artistic License. This License may be found at "
        + "http://www.opensource.org/licenses/artistic-license.php. "
        + "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";

    private final static Logger logger = Logger.getLogger("org.syrup.functions.BShell");

    private java.lang.Process p = null;

    /**
     */
    public Result execute(Context context)
    {
        boolean consume_command = true;

        // [TODO: Refactor so that Shell and BShell share the duplicate code]
        // See Shell for the implementation comments.
        try
        {
            if (Utils.isFull(context.in_1_link()))
            {
                String command = new String(context.in_1_link().content().bytes());

                try
                {
                    // The following clutch is needed with JVM 1.4.2 and lower.
                    // For JVM 1.5 and higher it can be implemented much better.
                    String[] i = null;
                    String os = System.getProperty("os.name");
                    if (os.toLowerCase().indexOf("windows") >= 0)
                    {
                        String[] k =
                        {
                            "cmd.exe", "/C", command
                        };
                        i = k;
                    }
                    else
                    {
                        String[] k =
                        {
                            "sh", "-c", command
                        };
                        i = k;
                    }
                    /*
                     * Start the shell. Add shutdown hook to make sure that
                     * after JVM shutdown, the shell is also terminated.
                     */
                    p = Runtime.getRuntime().exec(i);
                    Runtime.getRuntime().addShutdownHook(this);
                }
                catch (Error e)
                {
                    if (p != null)
                    {
                        p.destroy();
                    }
                    throw new Exception("Process died exceptionally");
                }

                ByteArrayInputStream input = new ByteArrayInputStream(new byte[0]);
               

                if (Utils.isFull(context.in_2_link()))
                {
                    consume_command = false;
                    input = new ByteArrayInputStream(context.in_2_link().content().bytes());
                }

                ByteArrayOutputStream output = new ByteArrayOutputStream();
                ByteArrayOutputStream error = new ByteArrayOutputStream();

                BlobClientHandler w1 = new BlobClientHandler("get", input, p.getOutputStream());
                BlobClientHandler w2 = new BlobClientHandler("post", p.getInputStream(), output);
                Writer w3 = new Writer(p.getErrorStream(), error);

                p.waitFor();

                w1.join();
                w2.join();
                w3.join();

                if (w1.getException() != null)
                {
                    throw w1.getException();
                }

                if (w2.getException() != null)
                {
                    throw w2.getException();
                }

                if (w3.getException() != null)
                {
                    throw w3.getException();
                }

                if (error.size() > 0
                    && output.size() == 0)
                {
                    return new ResultImpl(context, consume_command, true, null, new DataImpl(error.toByteArray()));
                }
                else
                {
                    if (error.size() > 0)
                    {
                        return new ResultImpl(context, consume_command, true, new DataImpl(output.toByteArray()), new DataImpl(error.toByteArray()));
                    }
                    else
                    {
                        /*
                         * This indicates stdout without stderr.
                         */
                        if (output.size() > 0)
                        {
                            return new ResultImpl(context, consume_command, true, new DataImpl(output.toByteArray()), null);
                        }
                        else
                        {
                            return new ResultImpl(context, consume_command, true, null, null);
                        }
                    }
                }
            }
            else
            {
                throw new Exception("first input is mandatory");
            }
        }
        catch (Throwable e1)
        {
            return new ResultImpl(context, true, true, null, org.syrup.helpers.Utils.manageError(logger, e1, "BShell error"));
        }
        finally
        {
            Runtime.getRuntime().removeShutdownHook(this);
        }
    }

    /**
     * Main processing method for the BShell object
     */
    public void run()
    {
        p.destroy();
    }

    /**
     * Description of the Class
     *
     * @author Robbert van Dalen
     */
    private class BlobClientHandler extends Thread
    {
        public final String command;

        public final InputStream input;

        public final OutputStream output;

        public final BlobClient client;

        private Exception exception;

        /**
        
         */
        public BlobClientHandler(String c, InputStream i, OutputStream o)
            throws Exception
        {
            command = c;
            client = (BlobClient) (new InitialContext().lookup("syrupBlobClient"));
            input = i;
            output = o;
            this.start();
        }

        /**
         * Main processing method for the BlobClientHandler object
         */
        public void run()
        {
            try
            {
                if (command.equals("get"))
                {
                    client.get(input, output);
                }
                else if (command.equals("post"))
                {
                    client.post(input, output);
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
                try
                {
                    input.close();
                    output.close();
                }
                catch (Exception e)
                {
                    exception = e;
                }
            }
        }

        /**
         * Gets the exception attribute of the BlobClientHandler object
         *
         * @return The exception value
         */
        public Exception getException()
        {
            return exception;
        }
    }
}
TOP

Related Classes of org.syrup.functions.BShell$BlobClientHandler

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.