From 4086635cfaa04c8a184124048794398b0ba96a55 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 21 Oct 2023 12:03:43 +0200 Subject: [PATCH] Improve RCP launch --- .../src/org/argeo/api/cms/CmsDeployment.java | 13 ++++-- .../src/org/argeo/api}/cms/CmsSshd.java | 8 ++-- .../src/org/argeo/api/cms/ux/CmsView.java | 13 +++++- .../org/argeo/cms/jetty/JettyHttpServer.java | 12 ++++++ .../OSGI-INF/cmsSshServer.xml | 2 +- .../src/org/argeo/cms/ssh/CmsSshServer.java | 8 +++- org.argeo.cms/OSGI-INF/cmsDeployment.xml | 2 +- .../internal/runtime/CmsDeploymentImpl.java | 33 +++++++++++---- ...viceFactory.xml => equinoxJettyServer.xml} | 1 + .../equinox/org.argeo.cms.lib.equinox/bnd.bnd | 2 +- .../org/argeo/cms/web/CmsWebEntryPoint.java | 11 +++++ .../OSGI-INF/cmsRcpDBusLauncher.xml | 1 + .../OSGI-INF/cmsRcpDisplayFactory.xml | 4 ++ swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd | 1 + .../src/org/argeo/cms/ui/rcp/CmsRcpApp.java | 27 +++++++++++++ .../cms/ui/rcp/CmsRcpDisplayFactory.java | 40 ++++++++++++++----- .../argeo/cms/ui/rcp/CmsRcpHttpLauncher.java | 4 +- .../cms/ui/rcp/dbus/CmsRcpDBusLauncher.java | 10 ++++- .../dbus/CmsRcpFreeDesktopApplication.java | 8 +++- 19 files changed, 167 insertions(+), 33 deletions(-) rename {org.argeo.cms/src/org/argeo => org.argeo.api.cms/src/org/argeo/api}/cms/CmsSshd.java (59%) rename osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/{jettyServiceFactory.xml => equinoxJettyServer.xml} (90%) diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java b/org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java index d557816cb..ca1082c7d 100644 --- a/org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java +++ b/org.argeo.api.cms/src/org/argeo/api/cms/CmsDeployment.java @@ -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 props); -// -// Dictionary getProps(String factoryPid, String cn); + /** The local HTTP server, or null if none is expected. */ + CompletionStage getHttpServer(); + + /** The local SSH server, or null if none is expected. */ + CompletionStage getCmsSshd(); } diff --git a/org.argeo.cms/src/org/argeo/cms/CmsSshd.java b/org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java similarity index 59% rename from org.argeo.cms/src/org/argeo/cms/CmsSshd.java rename to org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java index 41968be7e..ec44e57ec 100644 --- a/org.argeo.cms/src/org/argeo/cms/CmsSshd.java +++ b/org.argeo.api.cms/src/org/argeo/api/cms/CmsSshd.java @@ -1,9 +1,11 @@ -package org.argeo.cms; +package org.argeo.api.cms; -import org.argeo.api.cms.CmsConstants; +import java.net.InetSocketAddress; -/** Just a marker interface for the time being. */ +/** 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(); } diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java b/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java index a36baf8e0..121e4bdcb 100644 --- a/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java +++ b/org.argeo.api.cms/src/org/argeo/api/cms/ux/CmsView.java @@ -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); - CmsImageManager getImageManager(); + CmsImageManager 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. diff --git a/org.argeo.cms.lib.jetty/src/org/argeo/cms/jetty/JettyHttpServer.java b/org.argeo.cms.lib.jetty/src/org/argeo/cms/jetty/JettyHttpServer.java index 1254781e8..98975c3c8 100644 --- a/org.argeo.cms.lib.jetty/src/org/argeo/cms/jetty/JettyHttpServer.java +++ b/org.argeo.cms.lib.jetty/src/org/argeo/cms/jetty/JettyHttpServer.java @@ -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) diff --git a/org.argeo.cms.lib.sshd/OSGI-INF/cmsSshServer.xml b/org.argeo.cms.lib.sshd/OSGI-INF/cmsSshServer.xml index 987b97745..8117b03b8 100644 --- a/org.argeo.cms.lib.sshd/OSGI-INF/cmsSshServer.xml +++ b/org.argeo.cms.lib.sshd/OSGI-INF/cmsSshServer.xml @@ -3,6 +3,6 @@ - + diff --git a/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/CmsSshServer.java b/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/CmsSshServer.java index f5609a37d..8a6def33a 100644 --- a/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/CmsSshServer.java +++ b/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/CmsSshServer.java @@ -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); + } + } diff --git a/org.argeo.cms/OSGI-INF/cmsDeployment.xml b/org.argeo.cms/OSGI-INF/cmsDeployment.xml index 66541827d..ee86ad59a 100644 --- a/org.argeo.cms/OSGI-INF/cmsDeployment.xml +++ b/org.argeo.cms/OSGI-INF/cmsDeployment.xml @@ -2,7 +2,7 @@ - + diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java index e2d1fb97a..265cb34a0 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsDeploymentImpl.java @@ -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 = new CompletableFuture<>(); private Map httpHandlers = new TreeMap<>(); private Map httpAuthenticators = new TreeMap<>(); // SSHD - private CmsSshd cmsSshd; + private CompletableFuture 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 getHttpServer() { + return httpServer.minimalCompletionStage(); + } + + @Override + public CompletionStage getCmsSshd() { + return cmsSshd.minimalCompletionStage(); } } diff --git a/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml b/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml similarity index 90% rename from osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml rename to osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml index 6a1336220..1b75ea2a4 100644 --- a/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/jettyServiceFactory.xml +++ b/osgi/equinox/org.argeo.cms.lib.equinox/OSGI-INF/equinoxJettyServer.xml @@ -5,5 +5,6 @@ + diff --git a/osgi/equinox/org.argeo.cms.lib.equinox/bnd.bnd b/osgi/equinox/org.argeo.cms.lib.equinox/bnd.bnd index 2c83158e2..2ced2a26c 100644 --- a/osgi/equinox/org.argeo.cms.lib.equinox/bnd.bnd +++ b/osgi/equinox/org.argeo.cms.lib.equinox/bnd.bnd @@ -1,2 +1,2 @@ Service-Component: \ -OSGI-INF/jettyServiceFactory.xml,\ +OSGI-INF/equinoxJettyServer.xml,\ diff --git a/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java b/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java index 216dc3654..238975543 100644 --- a/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java +++ b/swt/rap/org.argeo.cms.swt.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java @@ -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 */ diff --git a/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDBusLauncher.xml b/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDBusLauncher.xml index e8bfefb3f..f66bf4b42 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDBusLauncher.xml +++ b/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDBusLauncher.xml @@ -3,4 +3,5 @@ + diff --git a/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDisplayFactory.xml b/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDisplayFactory.xml index 8b1d14684..41cae5393 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDisplayFactory.xml +++ b/swt/rcp/org.argeo.cms.swt.rcp/OSGI-INF/cmsRcpDisplayFactory.xml @@ -1,4 +1,8 @@ + + + + diff --git a/swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd b/swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd index 6f3758250..80b5bcd33 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd +++ b/swt/rcp/org.argeo.cms.swt.rcp/bnd.bnd @@ -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,\ diff --git a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java index a88ff3824..77aeae061 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java +++ b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java @@ -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 */ diff --git a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpDisplayFactory.java b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpDisplayFactory.java index 63a1fd84e..cd554de9d 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpDisplayFactory.java +++ b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpDisplayFactory.java @@ -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; + } + } diff --git a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java index 6246b0d0d..8b81e6698 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java +++ b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java @@ -25,6 +25,8 @@ public class CmsRcpHttpLauncher { private final static Logger logger = System.getLogger(CmsRcpHttpLauncher.class.getName()); private CompletableFuture 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); } diff --git a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpDBusLauncher.java b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpDBusLauncher.java index ea6905757..34190b005 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpDBusLauncher.java +++ b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpDBusLauncher.java @@ -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 = new CompletableFuture<>(); private Map apps = new HashMap<>(); + private CmsRcpDisplayFactory cmsRcpDisplayFactory; + public void start() { } @@ -24,7 +27,8 @@ public class CmsRcpDBusLauncher { public void addCmsApp(CmsApp cmsApp, Map 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; + } + } diff --git a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpFreeDesktopApplication.java b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpFreeDesktopApplication.java index 98c84fa41..f1962f70a 100644 --- a/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpFreeDesktopApplication.java +++ b/swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/dbus/CmsRcpFreeDesktopApplication.java @@ -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 -- 2.30.2