Package pushy

Source Code of pushy.Client

/*
* Copyright (c) 2009, 2011 Andrew Wilkins <axwalk@gmail.com>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package pushy;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.net.JarURLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import pushy.modules.ModuleFactory;
import pushy.internal.Connection;

/**
* The Client class manages a Pushy connection, and provides the methods to
* access objects in the remote Python process.
*/
public class Client
{
    private static final String jarPath =
        getJarPath(Client.class.getResource("Client.class"));

    // Determine the path to the jar file that defines Pushy, which will be
    // used to import the 'pushy' module.
    private static String getJarPath(URL url)
    {
        try
        {
            if (url.getProtocol().equals("jar"))
            {
                JarURLConnection conn = (JarURLConnection)url.openConnection();
                return conn.getJarFile().getName();
            }
            else if (url.getProtocol().equals("bundleresource"))
            {
                // This is a bit of a hack. If the URL is a bundleresource
                // (i.e. loaded from a OSGi bundle), then we can get a
                // "local URL" which is a file or jar URL.
                URLConnection conn = url.openConnection();
                java.lang.reflect.Method getLocalURL =
                    conn.getClass().getMethod("getLocalURL", null);
                URL localURL = (URL)getLocalURL.invoke(conn, null);
                return getJarPath(localURL);
            }
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }
        return null;
    }

    private Process pushyServer;
    private Connection connection;
    private PushyObject remoteConnection;
    private PushyObject remoteEvaluate;
    private PushyObject remotePutfile;
    private PushyObject remoteGetfile;
    private PushyObject remoteClose;
    private Map modules = new HashMap();
    private RemoteSystem system;

    /**
     * Create a Pushy connection, with the specified address.
     *
     * @param address The Pushy address to connect with.
     */
    public Client(String address) throws IOException
    {
        this(address, null);
    }

    /**
     * Create a Pushy connection, with the specified address and a map of
     * arbitrary keyword arguments.
     *
     * @param address The Pushy address to connect with.
     * @param properties Keyword arguments to pass to 'pushy.connect'.
     */
    public Client(String address, Map properties) throws IOException
    {
        // If a null address was specified, default to a local connection.
        if (address == null)
            address = "local:";
        else
            address = address.trim();

        String pushyLoaderProgram =
            "import sys;" +
            "sys.path.insert(0, sys.argv[1]);" +
            "import pushy.server;" +
            "pushy.server.serve_forever(sys.stdin, sys.stdout)";

        // Start XML-RPC server process.
        String[] args =
            new String[]{"python", "-u", "-c", pushyLoaderProgram, jarPath};
        pushyServer = Runtime.getRuntime().exec(args);

        try
        {
            // Create the connection.
            connection = new Connection(pushyServer.getInputStream(),
                                        pushyServer.getOutputStream());

            // If the address is non-local, create a tunnelled connection.
            if (!address.equals("local:"))
            {
                PushyObject pushyModule =
                    (PushyObject)connection.evaluate(
                        "__import__('pushy')", null, null);
                PushyObject connectMethod =
                    (PushyObject)pushyModule.__getattr__("connect");
                remoteConnection =
                    (PushyObject)connectMethod.__call__(
                        new Object[]{address}, properties);
                remoteEvaluate =
                    (PushyObject)remoteConnection.__getattr__("eval");
                remotePutfile =
                    (PushyObject)remoteConnection.__getattr__("putfile");
                remoteGetfile =
                    (PushyObject)remoteConnection.__getattr__("getfile");
                remoteClose =
                    (PushyObject)remoteConnection.__getattr__("close");
            }
        }
        catch (Throwable e)
        {
            e.printStackTrace();
            try
            {
                BufferedReader reader =
                    new BufferedReader(
                            new InputStreamReader(
                                    pushyServer.getErrorStream()));
                String line = reader.readLine();
                while (line != null)
                {
                    System.err.println(line);
                    line = reader.readLine();
                }
            }
            catch (Throwable e2)
            {
                e2.printStackTrace();
            }
            pushyServer.destroy();
            throw new RuntimeException(e);
        }
        pushyServer.getErrorStream().close();
    }

    protected void finalize()
    {
        close();
        try {
            super.finalize();
        } catch (Throwable e) {}
    }

    /**
     * Close the server.
     */
    public void close()
    {
        if (pushyServer != null)
        {
            synchronized (this)
            {
                if (pushyServer != null)
                {
                    try
                    {
                        if (remoteClose != null)
                            remoteClose.__call__();
                        pushyServer.getOutputStream().close();
                        pushyServer.getInputStream().close();
                    }
                    catch (java.io.IOException e) {}
                    pushyServer.destroy();
                    pushyServer = null;
                }
            }
        }
    }

    /**
     * Evaluate an expression.
     */
    public Object evaluate(String expression)
    {
        return evaluate(expression, null);
    }

    /**
     * Evaluate an expression.
     */
    public Object evaluate(String expression, Map locals)
    {
        return evaluate(expression, locals, null);
    }

    /**
     * Evaluate an expression.
     */
    public Object evaluate(String expression, Map locals, Map globals)
    {
        if (remoteEvaluate == null)
            return connection.evaluate(expression, locals, globals);
        Object[] args = new Object[]{expression, locals, globals};
        return remoteEvaluate.__call__(args);
    }

    /**
     * Acquire a reference to a module.
     *
     * @param name The name of the module.
     * @return A subclass of pushy.Module.
     */
    public synchronized Module getModule(String name)
    {
        Module module = (Module)modules.get(name);
        if (module == null)
        {
            module = ModuleFactory.createModule(this, name);
            modules.put(name, module);
        }
        return module;
    }

    /**
     * Copy a local file to the remote system, using a transport-specific
     * mechanism for greater efficiency where available.
     *
     * @param localFile The path of the local file to copy from.
     * @param remoteFile The path of the remote file to copy to.
     */
    public void putfile(String localFile, String remoteFile)
    {
        if (remotePutfile == null)
            pushy.internal.LocalFileIO.copyfile(localFile, remoteFile);
        else
            remotePutfile.__call__(new Object[]{localFile, remoteFile});
    }

    /**
     * Copy a remote file to the local system, using a transport-specific
     * mechanism for greater efficiency where available.
     *
     * @param remoteFile The path of the remote file to copy from.
     * @param localFile The path of the local file to copy to.
     */
    public void getfile(String remoteFile, String localFile)
    {
        if (remotePutfile == null)
            pushy.internal.LocalFileIO.copyfile(remoteFile, localFile);
        else
            remoteGetfile.__call__(new Object[]{remoteFile, localFile});
    }

    /**
     * Get an instance of RemoteSystem, which mimics java.lang.System.
     */
    public RemoteSystem getSystem()
    {
        if (system == null) {
            synchronized (this) {
                if (system == null)
                    system = new RemoteSystem(this);
            }
        }
        return system;
    }

    /**
     * Determine whether or not garbage collection of proxies is enabled.
     *
     * If garbage collection is enabled, weak references will be created for
     * proxies. This is the default.
     */
    public boolean isGCEnabled()
    {
        return connection.isGCEnabled();
    }

    /**
     * Enable or disable garbage collection of proxies.
     */
    public void setGCEnabled(boolean enabled)
    {
        connection.setGCEnabled(enabled);
    }

    /**
     * Get the garbage collection interval, in milliseconds.
     *
     * This is the amount of time in between sending of "delete" messages.
     */
    public int getGCIntervalMillis()
    {
        return connection.getGCIntervalMillis();
    }

    /**
     * Set the garbage collection interval, in milliseconds.
     */
    public void setGCIntervalMillis(int intervalMillis)
    {
        connection.setGCIntervalMillis(intervalMillis);
    }
}
TOP

Related Classes of pushy.Client

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.