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

org.freedesktop.dbus.DirectConnection Maven / Gradle / Ivy

Go to download

Improved version of the DBus-Java library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/).

There is a newer version: 3.3.2
Show newest version
/*
   D-Bus Java Implementation
   Copyright (c) 2005-2006 Matthew Johnson

   This program is free software; you can redistribute it and/or modify it
   under the terms of either the GNU Lesser General Public License Version 2 or the
   Academic Free Licence Version 2.1.

   Full licence texts are included in the COPYING file with this program.
*/
package org.freedesktop.dbus;

import static org.freedesktop.dbus.Gettext.t;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Random;
import java.util.Vector;

import org.freedesktop.DBus;
import org.freedesktop.dbus.exceptions.DBusException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Handles a peer to peer connection between two applications withou a bus daemon.
 * 

* Signal Handlers and method calls from remote objects are run in their own threads, you MUST handle the concurrency issues. *

*/ public class DirectConnection extends AbstractConnection { private final Logger logger = LoggerFactory.getLogger(getClass()); /** * Create a direct connection to another application. * @param address The address to connect to. This is a standard D-Bus address, except that the additional parameter 'listen=true' should be added in the application which is creating the socket. * @throws DBusException on error */ public DirectConnection(String address) throws DBusException { super(address); try { transport = new Transport(addr, AbstractConnection.TIMEOUT); connected = true; } catch (IOException exIo) { if (EXCEPTION_DEBUG) { logger.error("", exIo); } throw new DBusException(t("Failed to connect to bus ") + exIo.getMessage()); } catch (ParseException exP) { if (EXCEPTION_DEBUG) { logger.error("", exP); } throw new DBusException(t("Failed to connect to bus ") + exP.getMessage()); } listen(); } /** * Creates a bus address for a randomly generated tcp port. * @return a random bus address. */ public static String createDynamicTCPSession() { String address = "tcp:host=localhost"; int port; try { ServerSocket s = new ServerSocket(); s.bind(null); port = s.getLocalPort(); s.close(); } catch (Exception e) { Random r = new Random(); port = 32768 + (Math.abs(r.nextInt()) % 28232); } address += ",port=" + port; address += ",guid=" + Transport.genGUID(); LoggerFactory.getLogger(DirectConnection.class).debug("Created Session address: " + address); return address; } /** * Creates a bus address for a randomly generated abstract unix socket. * @return a random bus address. */ public static String createDynamicSession() { String address = "unix:"; String path = "/tmp/dbus-XXXXXXXXXX"; Random r = new Random(); do { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append((char) ((Math.abs(r.nextInt()) % 26) + 65)); } path = path.replaceAll("..........$", sb.toString()); LoggerFactory.getLogger(DirectConnection.class).trace("Trying path " + path); } while ((new File(path)).exists()); address += "abstract=" + path; address += ",guid=" + Transport.genGUID(); LoggerFactory.getLogger(DirectConnection.class).debug("Created Session address: " + address); return address; } DBusInterface dynamicProxy(String path) throws DBusException { try { DBus.Introspectable intro = (DBus.Introspectable) getRemoteObject(path, DBus.Introspectable.class); String data = intro.Introspect(); String[] tags = data.split("[<>]"); Vector ifaces = new Vector(); for (String tag : tags) { if (tag.startsWith("interface")) { ifaces.add(tag.replaceAll("^interface *name *= *['\"]([^'\"]*)['\"].*$", "$1")); } } Vector> ifcs = new Vector>(); for (String iface : ifaces) { int j = 0; while (j >= 0) { try { ifcs.add(Class.forName(iface)); break; } catch (Exception e) { } j = iface.lastIndexOf("."); char[] cs = iface.toCharArray(); if (j >= 0) { cs[j] = '$'; iface = String.valueOf(cs); } } } if (ifcs.size() == 0) { throw new DBusException(t("Could not find an interface to cast to")); } RemoteObject ro = new RemoteObject(null, path, null, false); DBusInterface newi = (DBusInterface) Proxy.newProxyInstance(ifcs.get(0).getClassLoader(), ifcs.toArray(new Class[0]), new RemoteInvocationHandler(this, ro)); importedObjects.put(newi, ro); return newi; } catch (Exception e) { if (EXCEPTION_DEBUG) { logger.error("", e); } throw new DBusException(MessageFormat.format(t("Failed to create proxy object for {0}; reason: {1}."), new Object[] { path, e.getMessage() })); } } DBusInterface getExportedObject(String path) throws DBusException { ExportedObject o = null; synchronized (exportedObjects) { o = exportedObjects.get(path); } if (null != o && null == o.object.get()) { unExportObject(path); o = null; } if (null != o) { return o.object.get(); } return dynamicProxy(path); } /** * Return a reference to a remote object. * This method will always refer to the well known name (if given) rather than resolving it to a unique bus name. * In particular this means that if a process providing the well known name disappears and is taken over by another process * proxy objects gained by this method will make calls on the new proccess. * * This method will use bus introspection to determine the interfaces on a remote object and so * may block and may fail. The resulting proxy object will, however, be castable * to any interface it implements. It will also autostart the process if applicable. Also note * that the resulting proxy may fail to execute the correct method with overloaded methods * and that complex types may fail in interesting ways. Basically, if something odd happens, * try specifying the interface explicitly. * * @param objectpath The path on which the process is exporting the object. * @return A reference to a remote object. * @throws ClassCastException If type is not a sub-type of DBusInterface * @throws DBusException If busname or objectpath are incorrectly formatted. */ public DBusInterface getRemoteObject(String objectpath) throws DBusException { if (null == objectpath) { throw new DBusException(t("Invalid object path: null")); } if (!objectpath.matches(OBJECT_REGEX) || objectpath.length() > MAX_NAME_LENGTH) { throw new DBusException(t("Invalid object path: ") + objectpath); } return dynamicProxy(objectpath); } /** * Return a reference to a remote object. * This method will always refer to the well known name (if given) rather than resolving it to a unique bus name. * In particular this means that if a process providing the well known name disappears and is taken over by another process * proxy objects gained by this method will make calls on the new proccess. * @param objectpath The path on which the process is exporting the object. * @param type The interface they are exporting it on. This type must have the same full class name and exposed method signatures * as the interface the remote object is exporting. * @return A reference to a remote object. * @throws ClassCastException If type is not a sub-type of DBusInterface * @throws DBusException If busname or objectpath are incorrectly formatted or type is not in a package. */ public DBusInterface getRemoteObject(String objectpath, Class type) throws DBusException { if (null == objectpath) { throw new DBusException(t("Invalid object path: null")); } if (null == type) { throw new ClassCastException(t("Not A DBus Interface")); } if (!objectpath.matches(OBJECT_REGEX) || objectpath.length() > MAX_NAME_LENGTH) { throw new DBusException(t("Invalid object path: ") + objectpath); } if (!DBusInterface.class.isAssignableFrom(type)) { throw new ClassCastException(t("Not A DBus Interface")); } // don't let people import things which don't have a // valid D-Bus interface name if (type.getName().equals(type.getSimpleName())) { throw new DBusException(t("DBusInterfaces cannot be declared outside a package")); } RemoteObject ro = new RemoteObject(null, objectpath, type, false); DBusInterface i = (DBusInterface) Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, new RemoteInvocationHandler(this, ro)); importedObjects.put(i, ro); return i; } @Override protected void removeSigHandler(DBusMatchRule rule, DBusSigHandler handler) throws DBusException { SignalTuple key = new SignalTuple(rule.getInterface(), rule.getMember(), rule.getObject(), rule.getSource()); synchronized (handledSignals) { Vector> v = handledSignals.get(key); if (null != v) { v.remove(handler); if (0 == v.size()) { handledSignals.remove(key); } } } } @Override protected void addSigHandler(DBusMatchRule rule, DBusSigHandler handler) throws DBusException { SignalTuple key = new SignalTuple(rule.getInterface(), rule.getMember(), rule.getObject(), rule.getSource()); synchronized (handledSignals) { Vector> v = handledSignals.get(key); if (null == v) { v = new Vector>(); v.add(handler); handledSignals.put(key, v); } else { v.add(handler); } } } @Override DBusInterface getExportedObject(String source, String path) throws DBusException { return getExportedObject(path); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy