]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - swt/rcp/org.argeo.cms.swt.rcp/src/org/argeo/cms/ui/rcp/CmsRcpHttpLauncher.java
1 package org
.argeo
.cms
.ui
.rcp
;
3 import static java
.lang
.System
.Logger
.Level
.DEBUG
;
5 import java
.io
.IOException
;
6 import java
.lang
.System
.Logger
;
7 import java
.lang
.System
.Logger
.Level
;
8 import java
.net
.DatagramSocket
;
9 import java
.net
.ServerSocket
;
11 import java
.nio
.charset
.StandardCharsets
;
12 import java
.nio
.file
.Files
;
13 import java
.nio
.file
.Path
;
15 import java
.util
.concurrent
.CompletableFuture
;
17 import org
.argeo
.api
.cms
.CmsApp
;
19 import com
.sun
.net
.httpserver
.HttpExchange
;
20 import com
.sun
.net
.httpserver
.HttpHandler
;
21 import com
.sun
.net
.httpserver
.HttpServer
;
23 /** Publishes one {@link CmsRcpServlet} per {@link CmsApp}. */
24 public class CmsRcpHttpLauncher
{
25 private final static Logger logger
= System
.getLogger(CmsRcpHttpLauncher
.class.getName());
26 private CompletableFuture
<HttpServer
> httpServer
= new CompletableFuture
<>();
32 public void destroy() {
33 Path runFile
= CmsRcpDisplayFactory
.getUrlRunFile();
35 if (Files
.exists(runFile
)) {
36 Files
.delete(runFile
);
38 } catch (IOException e
) {
39 logger
.log(Level
.ERROR
, "Cannot delete " + runFile
, e
);
43 public void addCmsApp(CmsApp cmsApp
, Map
<String
, String
> properties
) {
44 final String contextName
= properties
.get(CmsApp
.CONTEXT_NAME_PROPERTY
);
45 if (contextName
!= null) {
46 httpServer
.thenAcceptAsync((httpServer
) -> {
47 httpServer
.createContext("/" + contextName
, new HttpHandler() {
50 public void handle(HttpExchange exchange
) throws IOException
{
51 String path
= exchange
.getRequestURI().getPath();
52 String uiName
= path
!= null ? path
.substring(path
.lastIndexOf('/') + 1) : "";
53 CmsRcpDisplayFactory
.openCmsApp(cmsApp
, uiName
, null);
54 exchange
.sendResponseHeaders(200, -1);
55 logger
.log(Level
.DEBUG
, "Opened RCP UI " + uiName
+ " of CMS App /" + contextName
);
58 }).exceptionally(e
-> {
59 logger
.log(Level
.ERROR
, "Cannot register RCO app " + contextName
, e
);
62 logger
.log(Level
.DEBUG
, "Registered RCP CMS APP /" + contextName
);
66 public void removeCmsApp(CmsApp cmsApp
, Map
<String
, String
> properties
) {
67 String contextName
= properties
.get(CmsApp
.CONTEXT_NAME_PROPERTY
);
68 if (contextName
!= null) {
69 httpServer
.thenAcceptAsync((httpServer
) -> {
70 httpServer
.removeContext("/" + contextName
);
75 public void setHttpServer(HttpServer httpServer
) {
76 Integer httpPort
= httpServer
.getAddress().getPort();
77 String baseUrl
= "http://localhost:" + httpPort
+ "/";
78 Path runFile
= CmsRcpDisplayFactory
.getUrlRunFile();
80 if (!Files
.exists(runFile
)) {
81 Files
.createDirectories(runFile
.getParent());
82 // TODO give read permission only to the owner
83 Files
.createFile(runFile
);
85 URI uri
= URI
.create(Files
.readString(runFile
));
86 if (!httpPort
.equals(uri
.getPort()))
87 if (!isPortAvailable(uri
.getPort())) {
88 throw new IllegalStateException("Another CMS is running on " + runFile
);
90 logger
.log(Level
.WARNING
,
91 "Run file " + runFile
+ " found but port of " + uri
+ " is available. Overwriting...");
94 Files
.writeString(runFile
, baseUrl
, StandardCharsets
.UTF_8
);
95 } catch (IOException e
) {
96 throw new RuntimeException("Cannot write run file to " + runFile
, e
);
98 logger
.log(DEBUG
, "RCP available under " + baseUrl
+ ", written to " + runFile
);
99 this.httpServer
.complete(httpServer
);
102 protected boolean isPortAvailable(int port
) {
103 ServerSocket ss
= null;
104 DatagramSocket ds
= null;
106 ss
= new ServerSocket(port
);
107 ss
.setReuseAddress(true);
108 ds
= new DatagramSocket(port
);
109 ds
.setReuseAddress(true);
111 } catch (IOException e
) {
120 } catch (IOException e
) {
121 /* should not be thrown */