Introduce DBus support
[lgpl/argeo-commons.git] / org.argeo.cms.lib.dbus / src / org / argeo / cms / dbus / CmsDBusImpl.java
diff --git a/org.argeo.cms.lib.dbus/src/org/argeo/cms/dbus/CmsDBusImpl.java b/org.argeo.cms.lib.dbus/src/org/argeo/cms/dbus/CmsDBusImpl.java
new file mode 100644 (file)
index 0000000..b9a202b
--- /dev/null
@@ -0,0 +1,86 @@
+package org.argeo.cms.dbus;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.argeo.api.cms.CmsEventBus;
+import org.argeo.api.cms.CmsLog;
+import org.freedesktop.dbus.bin.EmbeddedDBusDaemon;
+import org.freedesktop.dbus.connections.BusAddress;
+import org.freedesktop.dbus.connections.impl.DBusConnection;
+import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder;
+import org.freedesktop.dbus.exceptions.DBusException;
+
+public class CmsDBusImpl implements CmsDBus {
+       private final static CmsLog log = CmsLog.getLog(CmsDBusImpl.class);
+
+       private BusAddress sessionBusAddress;
+
+       private EmbeddedDBusDaemon dBusDaemon;
+
+       private CmsEventBus cmsEventBus;
+
+       public void start() {
+               try {
+                       final String envSessionBusAddress = System.getenv(DBUS_SESSION_BUS_ADDRESS);
+                       if (envSessionBusAddress != null) {
+                               sessionBusAddress = BusAddress.of(envSessionBusAddress);
+                               
+                               // !! We must first initialise a connection, otherwise there are classloader issues later on 
+                               try (DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress)
+                                               .withShared(false).build()) {
+
+                               }
+                               log.debug(() -> "Found session DBus with address " + sessionBusAddress);
+                       } else {
+                               Path socketLocation = Paths.get(System.getProperty("user.home"), ".cache", "argeo", "bus");
+                               Files.createDirectories(socketLocation.getParent());
+                               // TODO escape : on Windows?
+                               String embeddedSessionBusAddress = "unix:path=" + socketLocation.toUri().getPath();
+                               dBusDaemon = new EmbeddedDBusDaemon(embeddedSessionBusAddress);
+                               dBusDaemon.startInBackgroundAndWait(30 * 1000);
+
+                               sessionBusAddress = BusAddress.of(embeddedSessionBusAddress);
+                               try (DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress)
+                                               .withShared(false).build()) {
+
+                               }
+                               log.debug(() -> "Started embedded session DBus with address " + sessionBusAddress);
+
+                               // TODO set environment variable?
+                       }
+               } catch (DBusException | IOException e) {
+                       throw new IllegalStateException("Cannot find a session bus", e);
+               }
+       }
+
+       public void stop() {
+               if (dBusDaemon != null) {
+                       try {
+                               dBusDaemon.close();
+                       } catch (IOException e) {
+                               log.error("Cannot close embedded DBus daemon", e);
+                       }
+               }
+       }
+
+       @Override
+       public DBusConnection openSessionConnection() {
+               try {
+                       DBusConnection dBusConnection = DBusConnectionBuilder.forAddress(sessionBusAddress).withShared(false)
+                                       .build();
+                       // TODO track all connections?
+                       return dBusConnection;
+               } catch (DBusException e) {
+                       e.printStackTrace();
+                       throw new IllegalStateException("Cannot open connection to session DBus", e);
+               }
+       }
+
+       public void setCmsEventBus(CmsEventBus cmsEventBus) {
+               this.cmsEventBus = cmsEventBus;
+       }
+
+}