]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CmsJShell.java
aec3da1f6fb5a7b1da6151f4455ec2a0aca50bc5
[lgpl/argeo-commons.git] / CmsJShell.java
1 package org.argeo.cms.jshell;
2
3 import java.io.IOException;
4 import java.nio.file.FileSystems;
5 import java.nio.file.Files;
6 import java.nio.file.Path;
7 import java.nio.file.StandardWatchEventKinds;
8 import java.nio.file.WatchEvent;
9 import java.nio.file.WatchKey;
10 import java.nio.file.WatchService;
11 import java.util.HashMap;
12 import java.util.Map;
13 import java.util.UUID;
14
15 import org.argeo.api.cms.CmsLog;
16 import org.argeo.api.cms.CmsState;
17 import org.argeo.api.uuid.UuidFactory;
18 import org.argeo.cms.util.OS;
19
20 public class CmsJShell {
21 private final static CmsLog log = CmsLog.getLog(CmsJShell.class);
22 static ClassLoader loader = CmsJShell.class.getClassLoader();
23
24 public static UuidFactory uuidFactory = null;
25
26 private CmsState cmsState;
27
28 private Map<Path, LocalJShellSession> localSessions = new HashMap<>();
29
30 private Path localBase;
31 private Path linkedDir;
32
33 public void start() throws Exception {
34
35 // Path localBase = cmsState.getStatePath("org.argeo.cms.jshell/local");
36 UUID stateUuid = cmsState.getUuid();
37
38 // TODO centralise state run dir
39 Path stateRunDir = OS.getRunDir().resolve(stateUuid.toString());
40 localBase = stateRunDir.resolve("jsh");
41 Files.createDirectories(localBase);
42
43 linkedDir = Files.createSymbolicLink(cmsState.getStatePath("jsh"), localBase);
44
45 log.info("Local JShell on " + localBase + ", linked to " + linkedDir);
46
47 new Thread(() -> {
48 try {
49 WatchService watchService = FileSystems.getDefault().newWatchService();
50
51 localBase.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
52 StandardWatchEventKinds.ENTRY_DELETE);
53
54 WatchKey key;
55 while ((key = watchService.take()) != null) {
56 events: for (WatchEvent<?> event : key.pollEvents()) {
57 // System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + ".");
58 Path path = localBase.resolve((Path) event.context());
59 // sessions
60 if (Files.isSameFile(localBase, path.getParent())) {
61 if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
62 if (!Files.isDirectory(path)) {
63 log.warn("Ignoring " + path + " as it is not a directory");
64 continue events;
65 }
66 try {
67 UUID.fromString(path.getFileName().toString());
68 } catch (IllegalArgumentException e) {
69 log.warn("Ignoring " + path + " as it is not named as UUID");
70 continue events;
71 }
72
73 LocalJShellSession localSession = new LocalJShellSession(path);
74 localSessions.put(path, localSession);
75 } else if (StandardWatchEventKinds.ENTRY_DELETE.equals(event.kind())) {
76 // TODO clean up session
77 LocalJShellSession localSession = localSessions.remove(path);
78 localSession.cleanUp();
79 }
80 } else {
81 // if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
82 // Path sessionDir = path.getParent();
83 // LocalSession session = localSessions.get(sessionDir);
84 // if (session == null) {
85 // sessions: for (Path p : localSessions.keySet()) {
86 // if (Files.isSameFile(sessionDir, p)) {
87 // session = localSessions.get(p);
88 // break sessions;
89 // }
90 // }
91 // }
92 // if (session == null) {
93 // log.warn("Ignoring " + path + " as its parent is not a registered session");
94 // continue events;
95 // }
96 // session.addChild(path);
97 // }
98
99 }
100 }
101 key.reset();
102 }
103 } catch (IOException | InterruptedException e) {
104 e.printStackTrace();
105 }
106 }, "JSChell local sessions watcher").start();
107
108 // thread context class loader should be where the service is defined
109 // Thread.currentThread().setContextClassLoader(loader);
110 // JavaShellToolBuilder builder = JavaShellToolBuilder.builder();
111 //
112 // builder.start("--execution", "osgi:bundle(org.argeo.cms.jshell)");
113
114 }
115
116 // public void startX(BundleContext bc) {
117 // uuidFactory = new NoOpUuidFactory();
118 //
119 // List<String> locations = new ArrayList<>();
120 // for (Bundle bundle : bc.getBundles()) {
121 // locations.add(bundle.getLocation());
122 //// System.out.println(bundle.getLocation());
123 // }
124 //
125 // CmsState cmsState = (CmsState) bc.getService(bc.getServiceReference("org.argeo.api.cms.CmsState"));
126 // System.out.println(cmsState.getDeployProperties(CmsDeployProperty.HTTP_PORT.getProperty()));
127 // System.out.println(cmsState.getUuid());
128 //
129 // ExecutionControlProvider executionControlProvider = new ExecutionControlProvider() {
130 // @Override
131 // public String name() {
132 // return "name";
133 // }
134 //
135 // @Override
136 // public ExecutionControl generate(ExecutionEnv ee, Map<String, String> map) throws Throwable {
137 // return new LocalExecutionControl(new WrappingLoaderDelegate(loader));
138 //// Thread.currentThread().setContextClassLoader(loader);
139 //// return new DirectExecutionControl();
140 // }
141 // };
142 //
143 //// Thread.currentThread().setContextClassLoader(loader);
144 //
145 // try (JShell js = JShell.builder().executionEngine(executionControlProvider, null).build()) {
146 // js.addToClasspath("/home/mbaudier/dev/git/unstable/output/a2/org.argeo.cms/org.argeo.api.cms.2.3.jar");
147 // js.addToClasspath("/home/mbaudier/dev/git/unstable/output/a2/org.argeo.cms/org.argeo.cms.2.3.jar");
148 // js.addToClasspath(
149 // "/home/mbaudier/dev/git/unstable/output/a2/osgi/equinox/org.argeo.tp.osgi/org.eclipse.osgi.3.18.jar");
150 //// do {
151 // System.out.print("Enter some Java code: ");
152 // // String input = console.readLine();
153 // String imports = """
154 // import org.argeo.api.cms.*;
155 // import org.argeo.cms.*;
156 // import org.argeo.slc.jshell.*;
157 // """;
158 // js.eval(imports);
159 // String input = """
160 // var bc = org.osgi.framework.FrameworkUtil.getBundle(org.argeo.cms.CmsDeployProperty.class).getBundleContext();
161 // var cmsState =(org.argeo.api.cms.CmsState) bc.getService(bc.getServiceReference("org.argeo.api.cms.CmsState"));
162 // System.out.println(cmsState.getDeployProperties(org.argeo.cms.CmsDeployProperty.HTTP_PORT.getProperty()));
163 // cmsState.getUuid();
164 // """;
165 //// if (input == null) {
166 //// break;
167 //// }
168 //
169 // input.lines().forEach((l) -> {
170 //
171 // List<SnippetEvent> events = js.eval(l);
172 // for (SnippetEvent e : events) {
173 // StringBuilder sb = new StringBuilder();
174 // if (e.causeSnippet() == null) {
175 // // We have a snippet creation event
176 // switch (e.status()) {
177 // case VALID:
178 // sb.append("Successful ");
179 // break;
180 // case RECOVERABLE_DEFINED:
181 // sb.append("With unresolved references ");
182 // break;
183 // case RECOVERABLE_NOT_DEFINED:
184 // sb.append("Possibly reparable, failed ");
185 // break;
186 // case REJECTED:
187 // sb.append("Failed ");
188 // break;
189 // }
190 // if (e.previousStatus() == Status.NONEXISTENT) {
191 // sb.append("addition");
192 // } else {
193 // sb.append("modification");
194 // }
195 // sb.append(" of ");
196 // sb.append(e.snippet().source());
197 // System.out.println(sb);
198 // if (e.value() != null) {
199 // System.out.printf("Value is: %s\n", e.value());
200 // }
201 // System.out.flush();
202 // }
203 // }
204 // });
205 //// } while (true);
206 // }
207 // }
208
209 public void stop() {
210 try {
211 Files.delete(linkedDir);
212 } catch (IOException e) {
213 log.error("Cannot remove " + linkedDir);
214 }
215 }
216
217 public void setCmsState(CmsState cmsState) {
218 this.cmsState = cmsState;
219 }
220
221 // public static void main(String[] args) throws Exception {
222 // Pipe inPipe = Pipe.open();
223 // Pipe outPipe = Pipe.open();
224 //
225 // InputStream in = Channels.newInputStream(inPipe.source());
226 // OutputStream out = Channels.newOutputStream(outPipe.sink());
227 // JavaShellToolBuilder builder = JavaShellToolBuilder.builder();
228 // builder.in(in, null);
229 // builder.interactiveTerminal(true);
230 // builder.out(new PrintStream(out));
231 //
232 // UnixDomainSocketAddress ioSocketAddress = JShellClient.ioSocketAddress();
233 // Files.deleteIfExists(ioSocketAddress.getPath());
234 //
235 // try (ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX)) {
236 // serverChannel.bind(ioSocketAddress);
237 //
238 // try (SocketChannel channel = serverChannel.accept()) {
239 // new Thread(() -> {
240 //
241 // try {
242 // ByteBuffer buffer = ByteBuffer.allocate(1024);
243 // while (true) {
244 // if (channel.read(buffer) < 0)
245 // break;
246 // buffer.flip();
247 // inPipe.sink().write(buffer);
248 // buffer.rewind();
249 // }
250 // } catch (IOException e) {
251 // e.printStackTrace();
252 // }
253 // }, "Read in").start();
254 //
255 // new Thread(() -> {
256 //
257 // try {
258 // ByteBuffer buffer = ByteBuffer.allocate(1024);
259 // while (true) {
260 // if (outPipe.source().read(buffer) < 0)
261 // break;
262 // buffer.flip();
263 // channel.write(buffer);
264 // buffer.rewind();
265 // }
266 // } catch (IOException e) {
267 // e.printStackTrace();
268 // }
269 // }, "Write out").start();
270 //
271 // builder.start();
272 // }
273 // } finally {
274 // System.out.println("Completed");
275 // }
276 // }
277
278 }