Improve RCP launch
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 21 Oct 2023 10:03:43 +0000 (12:03 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 21 Oct 2023 10:03:43 +0000 (12:03 +0200)
21 files changed:
org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java
org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java [new file with mode: 0644]
org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java
org.argeo.cms.lib.jetty/src/org/argeo/cms/jetty/JettyHttpServer.java
org.argeo.cms.lib.sshd/OSGI-INF/cmsSshServer.xml
org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/CmsSshServer.java
org.argeo.cms/OSGI-INF/cmsDeployment.xml
org.argeo.cms/src/org/argeo/cms/CmsSshd.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java
osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml [new file with mode: 0644]
osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml [deleted file]
osgi/equinox/org.argeo.cms.lib.equinox/bnd.bnd
swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java
swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDBusLauncher.xml
swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDisplayFactory.xml
swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd
swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java
swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpDisplayFactory.java
swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java
swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpDBusLauncher.java
swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpFreeDesktopApplication.java

index d557816cb1a3bc927d449c2ae7232b307fef726b..ca1082c7db5ab3c07d9118e8fa9545447ec424a5 100644 (file)
@@ -1,9 +1,14 @@
 package org.argeo.api.cms;
 
+import java.util.concurrent.CompletionStage;
+
+import com.sun.net.httpserver.HttpServer;
+
 /** A configured node deployment. */
 public interface CmsDeployment {
-
-//     void addFactoryDeployConfig(String factoryPid, Dictionary<String, Object> props);
-//
-//     Dictionary<String, Object> getProps(String factoryPid, String cn);
+       /** The local HTTP server, or null if none is expected. */
+       CompletionStage<HttpServer> getHttpServer();
+       
+       /** The local SSH server, or null if none is expected. */
+       CompletionStage<CmsSshd> getCmsSshd();
 }
diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java b/org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java
new file mode 100644 (file)
index 0000000..ec44e57
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.api.cms;
+
+import java.net.InetSocketAddress;
+
+/** A local SSH server. */
+public interface CmsSshd {
+       final static String NODE_USERNAME_ALIAS = "user.name";
+       final static String DEFAULT_SSH_HOST_KEY_PATH = "private/" + CmsConstants.NODE + ".ser";
+
+       InetSocketAddress getAddress();
+}
index a36baf8e08b642cd2c7b625162494ae9710b9d14..121e4bdcbf601a654fc608aeda89ec895f4b4e3b 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.api.cms.ux;
 
+import java.net.URI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -9,7 +10,7 @@ import javax.security.auth.login.LoginContext;
 
 import org.argeo.api.cms.CmsSession;
 
-/** Provides interaction with the CMS system. */
+/** Provides UX interactions with the CMS system. */
 public interface CmsView {
        final static String CMS_VIEW_UID_PROPERTY = "argeo.cms.view.uid";
        // String KEY = "org.argeo.cms.ui.view";
@@ -31,10 +32,18 @@ public interface CmsView {
        // SERVICES
        void exception(Throwable e);
 
-       <V,M> CmsImageManager<V, M> getImageManager();
+       <V, M> CmsImageManager<V, M> getImageManager();
 
        boolean isAnonymous();
 
+       /**
+        * Translates to an URL that can be reached by a client, depending on its type.
+        * Typically, if a web interface asks for /path/on/the/web/server it will be
+        * returned without modifications; but a thin client will probably need to add a
+        * server and a port.
+        */
+       URI toBackendUri(String url);
+
        /**
         * Send an event to this topic. Does nothing by default., but if implemented it
         * MUST set the {@link #CMS_VIEW_UID_PROPERTY} in the properties.
index 1254781e81d0802201db9945801268058cd0c201..98975c3c843ad7c152a4c1815f738a812c6ca130 100644 (file)
@@ -2,11 +2,13 @@ package org.argeo.cms.jetty;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.security.NoSuchAlgorithmException;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ThreadPoolExecutor;
 
+import javax.net.ssl.SSLContext;
 import javax.servlet.ServletException;
 import javax.websocket.server.ServerContainer;
 
@@ -170,6 +172,16 @@ public class JettyHttpServer extends HttpsServer {
                        }
 
                        if (httpsEnabled) {
+                               if (httpsConfigurator == null) {
+                                       // we make sure that an HttpSConfigurator is set, so that clients can detect
+                                       // whether this server is HTTP or HTTPS
+                                       try {
+                                               httpsConfigurator = new HttpsConfigurator(SSLContext.getDefault());
+                                       } catch (NoSuchAlgorithmException e) {
+                                               throw new IllegalStateException("Cannot initalise SSL Context", e);
+                                       }
+                               }
+
                                SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
                                // sslContextFactory.setKeyStore(KeyS)
 
index 987b977459aef7473db12180e7afa7f78628eb25..8117b03b863a6aca0e3ba4feee89b0cc5142bfbd 100644 (file)
@@ -3,6 +3,6 @@
    <implementation class="org.argeo.cms.ssh.CmsSshServer"/>
    <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
    <service>
-      <provide interface="org.argeo.cms.CmsSshd"/>
+      <provide interface="org.argeo.api.cms.CmsSshd"/>
    </service>
 </scr:component>
index f5609a37d5f70e2786153c567f96e0d0759a5684..8a6def33ac631c2c88eaf8f8daa308c27394d4a4 100644 (file)
@@ -3,6 +3,7 @@ package org.argeo.cms.ssh;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
+import java.net.InetSocketAddress;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -39,9 +40,9 @@ import org.apache.sshd.sftp.server.SftpSubsystemFactory;
 import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsSshd;
 import org.argeo.api.cms.CmsState;
 import org.argeo.cms.CmsDeployProperty;
-import org.argeo.cms.CmsSshd;
 
 public class CmsSshServer implements CmsSshd {
        private final static CmsLog log = CmsLog.getLog(CmsSshServer.class);
@@ -215,4 +216,9 @@ public class CmsSshServer implements CmsSshd {
                this.cmsState = cmsState;
        }
 
+       @Override
+       public InetSocketAddress getAddress() {
+               return new InetSocketAddress(host, port);
+       }
+
 }
index 66541827db71f0e9af08059420aa7186fe8d9140..ee86ad59a720cebb083cfda96b48b48c40042f4b 100644 (file)
@@ -2,7 +2,7 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" immediate="true" name="CMS Deployment">
    <implementation class="org.argeo.cms.internal.runtime.CmsDeploymentImpl"/>
    <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-   <reference bind="setCmsSshd" cardinality="0..1" interface="org.argeo.cms.CmsSshd" policy="dynamic"/>
+   <reference bind="setCmsSshd" cardinality="0..1" interface="org.argeo.api.cms.CmsSshd" policy="dynamic"/>
    <reference bind="setHttpServer" cardinality="0..1" interface="com.sun.net.httpserver.HttpServer" policy="dynamic"/>
    <reference bind="addHttpHandler" unbind="removeHttpHandler" cardinality="0..n" interface="com.sun.net.httpserver.HttpHandler" policy="dynamic"/>
    <service>
diff --git a/org.argeo.cms/src/org/argeo/cms/CmsSshd.java b/org.argeo.cms/src/org/argeo/cms/CmsSshd.java
deleted file mode 100644 (file)
index 41968be..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.argeo.cms;
-
-import org.argeo.api.cms.CmsConstants;
-
-/** Just a marker interface for the time being. */
-public interface CmsSshd {
-       final static String NODE_USERNAME_ALIAS = "user.name";
-       final static String DEFAULT_SSH_HOST_KEY_PATH = "private/" + CmsConstants.NODE + ".ser";
-}
index e2d1fb97a592d38e6a64e85918353dbb5b49ce6a..265cb34a073b4443d65316f74749332d54b67695 100644 (file)
@@ -3,14 +3,17 @@ package org.argeo.cms.internal.runtime;
 import static org.argeo.api.cms.CmsConstants.CONTEXT_PATH;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.TreeMap;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
 
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsDeployment;
 import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsSshd;
 import org.argeo.api.cms.CmsState;
 import org.argeo.cms.CmsDeployProperty;
-import org.argeo.cms.CmsSshd;
 import org.argeo.cms.internal.http.CmsAuthenticator;
 import org.argeo.cms.internal.http.PublicCmsAuthenticator;
 
@@ -29,12 +32,12 @@ public class CmsDeploymentImpl implements CmsDeployment {
        private boolean sshdExpected = false;
 
        // HTTP
-       private HttpServer httpServer;
+       private CompletableFuture<HttpServer> httpServer = new CompletableFuture<>();
        private Map<String, HttpHandler> httpHandlers = new TreeMap<>();
        private Map<String, CmsAuthenticator> httpAuthenticators = new TreeMap<>();
 
        // SSHD
-       private CmsSshd cmsSshd;
+       private CompletableFuture<CmsSshd> cmsSshd = new CompletableFuture<>();
 
        public void start() {
                log.debug(() -> "CMS deployment available");
@@ -49,13 +52,18 @@ public class CmsDeploymentImpl implements CmsDeployment {
                String httpPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTP_PORT.getProperty());
                String httpsPort = this.cmsState.getDeployProperty(CmsDeployProperty.HTTPS_PORT.getProperty());
                httpExpected = httpPort != null || httpsPort != null;
+               if (!httpExpected)
+                       httpServer.complete(null);
 
                String sshdPort = this.cmsState.getDeployProperty(CmsDeployProperty.SSHD_PORT.getProperty());
                sshdExpected = sshdPort != null;
+               if (!sshdExpected)
+                       cmsSshd.complete(null);
        }
 
        public void setHttpServer(HttpServer httpServer) {
-               this.httpServer = httpServer;
+               Objects.requireNonNull(httpServer);
+               this.httpServer.complete(httpServer);
                // create contexts whose handles had already been published
                for (String contextPath : httpHandlers.keySet()) {
                        HttpHandler httpHandler = httpHandlers.get(contextPath);
@@ -82,7 +90,7 @@ public class CmsDeploymentImpl implements CmsDeployment {
        }
 
        public void createHttpContext(String contextPath, HttpHandler httpHandler, CmsAuthenticator authenticator) {
-               HttpContext httpContext = httpServer.createContext(contextPath);
+               HttpContext httpContext = httpServer.join().createContext(contextPath);
                // we want to set the authenticator BEFORE the handler actually becomes active
                httpContext.setAuthenticator(authenticator);
                httpContext.setHandler(httpHandler);
@@ -96,7 +104,7 @@ public class CmsDeploymentImpl implements CmsDeployment {
                httpHandlers.remove(contextPath);
                if (httpServer == null)
                        return;
-               httpServer.removeContext(contextPath);
+               httpServer.join().removeContext(contextPath);
                log.debug(() -> "Removed handler " + contextPath + " : " + httpHandler.getClass().getName());
        }
 
@@ -109,7 +117,18 @@ public class CmsDeploymentImpl implements CmsDeployment {
        }
 
        public void setCmsSshd(CmsSshd cmsSshd) {
-               this.cmsSshd = cmsSshd;
+               Objects.requireNonNull(cmsSshd);
+               this.cmsSshd.complete(cmsSshd);
+       }
+
+       @Override
+       public CompletionStage<HttpServer> getHttpServer() {
+               return httpServer.minimalCompletionStage();
+       }
+
+       @Override
+       public CompletionStage<CmsSshd> getCmsSshd() {
+               return cmsSshd.minimalCompletionStage();
        }
 
 }
diff --git a/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml b/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml
new file mode 100644 (file)
index 0000000..1b75ea2
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" activate="start" deactivate="stop" name="Jetty Service Factory">
+   <implementation class="org.argeo.cms.equinox.http.jetty.EquinoxJettyServer"/>
+   <property name="service.pid" type="String" value="org.argeo.equinox.jetty.config"/>
+   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
+   <service>
+      <provide interface="com.sun.net.httpserver.HttpServer"/>
+      <provide interface="com.sun.net.httpserver.HttpsServer"/>
+   </service>
+</scr:component>
diff --git a/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml b/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml
deleted file mode 100644 (file)
index 6a13362..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" activate="start" deactivate="stop" name="Jetty Service Factory">
-   <implementation class="org.argeo.cms.equinox.http.jetty.EquinoxJettyServer"/>
-   <property name="service.pid" type="String" value="org.argeo.equinox.jetty.config"/>
-   <reference bind="setCmsState" cardinality="1..1" interface="org.argeo.api.cms.CmsState" name="CmsState" policy="static"/>
-   <service>
-      <provide interface="com.sun.net.httpserver.HttpServer"/>
-   </service>
-</scr:component>
index 2c83158e243cf69e0176afc5a7cc914c1f512806..2ced2a26c0d496cc2ba14301025a6dcf39bbee5f 100644 (file)
@@ -1,2 +1,2 @@
 Service-Component: \
-OSGI-INF/jettyServiceFactory.xml,\
+OSGI-INF/equinoxJettyServer.xml,\
index 216dc3654100b45f82ac2b5a07d33b558209916d..2389755432e6ccc6b381543f2cbab3a3fe45cd37 100644 (file)
@@ -2,6 +2,8 @@ package org.argeo.cms.web;
 
 import static org.eclipse.rap.rwt.internal.service.ContextProvider.getApplicationContext;
 
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.security.PrivilegedAction;
 import java.util.Locale;
 import java.util.UUID;
@@ -241,6 +243,15 @@ public class CmsWebEntryPoint extends AbstractSwtCmsView implements EntryPoint,
                return cmsSession;
        }
 
+       @Override
+       public URI toBackendUri(String url) {
+               try {
+                       return new URI(url);
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Cannot convert " + url, e);
+               }
+       }
+
        /*
         * EntryPoint IMPLEMENTATION
         */
index e8bfefb3f0594d8e5156e4bce95246a1002c7e5a..f66bf4b42138ffef67ba910e02dbe214380b7fa0 100644 (file)
@@ -3,4 +3,5 @@
    <implementation class="org.argeo.cms.ui.rcp.dbus.CmsRcpDBusLauncher"/>
    <reference bind="setCmsDBus" cardinality="1..1" interface="org.argeo.cms.dbus.CmsDBus" name="CmsDBus" policy="static"/>
    <reference bind="addCmsApp" cardinality="0..n" interface="org.argeo.api.cms.CmsApp" name="CmsApp" policy="dynamic" unbind="removeCmsApp"/>
+   <reference bind="setCmsRcpDisplayFactory" cardinality="1..1" interface="org.argeo.cms.ui.rcp.CmsRcpDisplayFactory" name="CmsRcpDisplayFactory" policy="static"/>
 </scr:component>
index 8b1d1468478f9a786ab3037ee89eaec06ad0a833..41cae5393e4f4ede3104e1b4d1ebc9a1d4c72a6f 100644 (file)
@@ -1,4 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="true" name="CMS RCP Display Factory">
    <implementation class="org.argeo.cms.ui.rcp.CmsRcpDisplayFactory"/>
+   <service>
+      <provide interface="org.argeo.cms.ui.rcp.CmsRcpDisplayFactory"/>
+   </service>
+   <reference bind="setCmsDeployment" cardinality="1..1" interface="org.argeo.api.cms.CmsDeployment" name="CmsDeployment" policy="static"/>
 </scr:component>
index 6f37582501b419080fd7a893f8e3c5bd9025fb6b..80b5bcd33fcb93fc87f1465d67202aabd161ac64 100644 (file)
@@ -2,6 +2,7 @@ Bundle-SymbolicName: org.argeo.cms.swt.rcp;singleton=true
 
 Import-Package:\
 org.argeo.cms.auth,\
+org.argeo.api.acr,\
 org.eclipse.swt,\
 org.eclipse.swt.widgets,\
 org.eclipse.swt.graphics,\
index a88ff3824fa07c2ee2d02d093104ce0ad93060fd..77aeae061fc780a80786477864f8a0391760fe18 100644 (file)
@@ -2,6 +2,8 @@ package org.argeo.cms.ui.rcp;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.security.PrivilegedAction;
 import java.util.Map;
 import java.util.UUID;
@@ -15,10 +17,12 @@ import org.argeo.api.cms.CmsAuth;
 import org.argeo.api.cms.CmsEventBus;
 import org.argeo.api.cms.CmsLog;
 import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.ux.CmsImageManager;
 import org.argeo.api.cms.ux.CmsTheme;
 import org.argeo.api.cms.ux.CmsView;
 import org.argeo.cms.swt.AbstractSwtCmsView;
 import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.acr.AcrSwtImageManager;
 import org.eclipse.e4.ui.css.core.engine.CSSEngine;
 import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler;
 import org.eclipse.e4.ui.css.swt.engine.CSSSWTEngineImpl;
@@ -36,12 +40,17 @@ public class CmsRcpApp extends AbstractSwtCmsView implements CmsView {
 
        private CSSEngine cssEngine;
 
+       private String httpServerBase;
+
        public CmsRcpApp(String uiName) {
                super(uiName);
                uid = UUID.randomUUID().toString();
        }
 
+       @SuppressWarnings("rawtypes")
        public void initRcpApp() {
+               imageManager = (CmsImageManager) new AcrSwtImageManager();
+
                display = Display.getCurrent();
                shell = new Shell(display);
                shell.setText("Argeo CMS");
@@ -153,6 +162,24 @@ public class CmsRcpApp extends AbstractSwtCmsView implements CmsView {
                return cmsApp;
        }
 
+       @Override
+       public URI toBackendUri(String url) {
+               try {
+                       URI u = new URI(url);
+                       if (u.getHost() == null) {
+                               // TODO make it more robust
+                               u = new URI(httpServerBase + url);
+                       }
+                       return u;
+               } catch (URISyntaxException e) {
+                       throw new IllegalArgumentException("Cannot convert " + url, e);
+               }
+       }
+
+       public void setHttpServerBase(String httpServerBase) {
+               this.httpServerBase = httpServerBase;
+       }
+
        /*
         * DEPENDENCY INJECTION
         */
index 63a1fd84ebb76ce6dc7f9da3d9d924e807871143..cd554de9d1ec09f63616a11dd1510b99ecd5bc67 100644 (file)
@@ -2,12 +2,15 @@ package org.argeo.cms.ui.rcp;
 
 import java.lang.System.Logger;
 import java.lang.System.Logger.Level;
+import java.net.InetSocketAddress;
 import java.nio.file.Path;
 
 import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsDeployment;
 import org.argeo.cms.util.OS;
 import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.widgets.Display;
+import com.sun.net.httpserver.HttpsServer;
 
 /** Creates the SWT {@link Display} in a dedicated thread. */
 public class CmsRcpDisplayFactory {
@@ -17,12 +20,14 @@ public class CmsRcpDisplayFactory {
        private final static String ARGEO_RCP_URL = "argeo.rcp.url";
 
        /** There is only one display in RCP mode */
-       private static Display display;
+       private Display display;
 
        private CmsUiThread uiThread;
 
        private boolean shutdown = false;
 
+       private CmsDeployment cmsDeployment;
+
        public void init() {
                uiThread = new CmsUiThread();
                uiThread.start();
@@ -74,21 +79,38 @@ public class CmsRcpDisplayFactory {
                }
        }
 
-       public static Display getDisplay() {
+       public Display getDisplay() {
                return display;
        }
 
-       public static void openCmsApp(CmsApp cmsApp, String uiName, DisposeListener disposeListener) {
-               CmsRcpDisplayFactory.getDisplay().syncExec(() -> {
-                       CmsRcpApp cmsRcpApp = new CmsRcpApp(uiName);
-                       cmsRcpApp.setCmsApp(cmsApp, null);
-                       cmsRcpApp.initRcpApp();
-                       if (disposeListener != null)
-                               cmsRcpApp.getShell().addDisposeListener(disposeListener);
+       public void openCmsApp(CmsApp cmsApp, String uiName, DisposeListener disposeListener) {
+               cmsDeployment.getHttpServer().thenAccept((httpServer) -> {
+                       getDisplay().syncExec(() -> {
+                               CmsRcpApp cmsRcpApp = new CmsRcpApp(uiName);
+                               cmsRcpApp.setCmsApp(cmsApp, null);
+                               if (httpServer != null) {
+                                       InetSocketAddress addr = httpServer.getAddress();
+                                       String scheme = "http";
+                                       if (httpServer instanceof HttpsServer httpsServer) {
+                                               if (httpsServer.getHttpsConfigurator() != null)
+                                                       scheme = "https";
+                                       }
+                                       String httpServerBase = scheme + "://" + addr.getHostString() + ":" + addr.getPort();
+                                       cmsRcpApp.setHttpServerBase(httpServerBase);
+                               }
+                               cmsRcpApp.initRcpApp();
+                               if (disposeListener != null)
+                                       cmsRcpApp.getShell().addDisposeListener(disposeListener);
+                       });
                });
        }
 
        public static Path getUrlRunFile() {
                return OS.getRunDir().resolve(CmsRcpDisplayFactory.ARGEO_RCP_URL);
        }
+
+       public void setCmsDeployment(CmsDeployment cmsDeployment) {
+               this.cmsDeployment = cmsDeployment;
+       }
+
 }
index 6246b0d0d13661316f546fb18e9bb74750f4b67f..8b81e6698ff5d5a6d3373ca074702e0dd62d31a9 100644 (file)
@@ -25,6 +25,8 @@ public class CmsRcpHttpLauncher {
        private final static Logger logger = System.getLogger(CmsRcpHttpLauncher.class.getName());
        private CompletableFuture<HttpServer> httpServer = new CompletableFuture<>();
 
+       private CmsRcpDisplayFactory cmsRcpDisplayFactory;
+       
        public void init() {
 
        }
@@ -50,7 +52,7 @@ public class CmsRcpHttpLauncher {
                                        public void handle(HttpExchange exchange) throws IOException {
                                                String path = exchange.getRequestURI().getPath();
                                                String uiName = path != null ? path.substring(path.lastIndexOf('/') + 1) : "";
-                                               CmsRcpDisplayFactory.openCmsApp(cmsApp, uiName, null);
+                                               cmsRcpDisplayFactory.openCmsApp(cmsApp, uiName, null);
                                                exchange.sendResponseHeaders(200, -1);
                                                logger.log(Level.DEBUG, "Opened RCP UI  " + uiName + " of  CMS App /" + contextName);
                                        }
index ea6905757adf6536914ce0b3514edd1aede6a12e..34190b005f14ac6f68526bb0be35a06409631537 100644 (file)
@@ -7,12 +7,15 @@ import java.util.concurrent.CompletableFuture;
 
 import org.argeo.api.cms.CmsApp;
 import org.argeo.cms.dbus.CmsDBus;
+import org.argeo.cms.ui.rcp.CmsRcpDisplayFactory;
 
 public class CmsRcpDBusLauncher {
        private CompletableFuture<CmsDBus> cmsDBus = new CompletableFuture<>();
 
        private Map<String, CmsRcpFreeDesktopApplication> apps = new HashMap<>();
 
+       private CmsRcpDisplayFactory cmsRcpDisplayFactory;
+
        public void start() {
 
        }
@@ -24,7 +27,8 @@ public class CmsRcpDBusLauncher {
        public void addCmsApp(CmsApp cmsApp, Map<String, String> properties) {
                final String contextName = properties.get(CmsApp.CONTEXT_NAME_PROPERTY);
                cmsDBus.thenAcceptAsync((cmsDBus) -> {
-                       CmsRcpFreeDesktopApplication application = new CmsRcpFreeDesktopApplication(cmsDBus, contextName, cmsApp);
+                       CmsRcpFreeDesktopApplication application = new CmsRcpFreeDesktopApplication(cmsRcpDisplayFactory, cmsDBus,
+                                       contextName, cmsApp);
                        apps.put(contextName, application);
                });
        }
@@ -45,4 +49,8 @@ public class CmsRcpDBusLauncher {
                this.cmsDBus.complete(cmsDBus);
        }
 
+       public void setCmsRcpDisplayFactory(CmsRcpDisplayFactory cmsRcpDisplayFactory) {
+               this.cmsRcpDisplayFactory = cmsRcpDisplayFactory;
+       }
+
 }
index 98c84fa41db214da95b445dc17fe883181b947dc..f1962f70a4eaf2d7f85639e68e23dd7ed5bd8a3a 100644 (file)
@@ -20,7 +20,11 @@ public class CmsRcpFreeDesktopApplication implements FreeDesktopApplication, Clo
 
        private DBusConnection dBusConnection;
 
-       public CmsRcpFreeDesktopApplication(CmsDBus cmsDBus, String contextName, CmsApp cmsApp) {
+       private CmsRcpDisplayFactory cmsRcpDisplayFactory;
+
+       public CmsRcpFreeDesktopApplication(CmsRcpDisplayFactory cmsRcpDisplayFactory, CmsDBus cmsDBus, String contextName,
+                       CmsApp cmsApp) {
+               this.cmsRcpDisplayFactory = cmsRcpDisplayFactory;
                // TODO find a better prefix and/or make it customisable
                this.path = "/org/argeo/cms/" + contextName;
                this.cmsApp = cmsApp;
@@ -50,7 +54,7 @@ public class CmsRcpFreeDesktopApplication implements FreeDesktopApplication, Clo
                // String uiName = path != null ? path.substring(path.lastIndexOf('/') + 1) :
                // "";
                String uiName = "app";
-               CmsRcpDisplayFactory.openCmsApp(cmsApp, uiName, null);
+               cmsRcpDisplayFactory.openCmsApp(cmsApp, uiName, null);
        }
 
        @Override