1 package org
.argeo
.cms
.jshell
;
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
;
13 import java
.util
.UUID
;
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
;
20 public class CmsJShell
{
21 private final static CmsLog log
= CmsLog
.getLog(CmsJShell
.class);
22 static ClassLoader loader
= CmsJShell
.class.getClassLoader();
24 public static UuidFactory uuidFactory
= null;
26 private CmsState cmsState
;
28 private Map
<Path
, LocalJShellSession
> localSessions
= new HashMap
<>();
30 private Path localBase
;
31 private Path linkedDir
;
33 public void start() throws Exception
{
35 // Path localBase = cmsState.getStatePath("org.argeo.cms.jshell/local");
36 UUID stateUuid
= cmsState
.getUuid();
38 // TODO centralise state run dir
39 Path stateRunDir
= OS
.getRunDir().resolve(stateUuid
.toString());
40 localBase
= stateRunDir
.resolve("jsh");
41 Files
.createDirectories(localBase
);
43 linkedDir
= Files
.createSymbolicLink(cmsState
.getStatePath("jsh"), localBase
);
45 log
.info("Local JShell on " + localBase
+ ", linked to " + linkedDir
);
49 WatchService watchService
= FileSystems
.getDefault().newWatchService();
51 localBase
.register(watchService
, StandardWatchEventKinds
.ENTRY_CREATE
,
52 StandardWatchEventKinds
.ENTRY_DELETE
);
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());
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");
67 UUID
.fromString(path
.getFileName().toString());
68 } catch (IllegalArgumentException e
) {
69 log
.warn("Ignoring " + path
+ " as it is not named as UUID");
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();
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);
92 // if (session == null) {
93 // log.warn("Ignoring " + path + " as its parent is not a registered session");
96 // session.addChild(path);
103 } catch (IOException
| InterruptedException e
) {
106 }, "JSChell local sessions watcher").start();
108 // thread context class loader should be where the service is defined
109 // Thread.currentThread().setContextClassLoader(loader);
110 // JavaShellToolBuilder builder = JavaShellToolBuilder.builder();
112 // builder.start("--execution", "osgi:bundle(org.argeo.cms.jshell)");
116 // public void startX(BundleContext bc) {
117 // uuidFactory = new NoOpUuidFactory();
119 // List<String> locations = new ArrayList<>();
120 // for (Bundle bundle : bc.getBundles()) {
121 // locations.add(bundle.getLocation());
122 //// System.out.println(bundle.getLocation());
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());
129 // ExecutionControlProvider executionControlProvider = new ExecutionControlProvider() {
131 // public String name() {
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();
143 //// Thread.currentThread().setContextClassLoader(loader);
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");
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.*;
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();
165 //// if (input == null) {
169 // input.lines().forEach((l) -> {
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()) {
178 // sb.append("Successful ");
180 // case RECOVERABLE_DEFINED:
181 // sb.append("With unresolved references ");
183 // case RECOVERABLE_NOT_DEFINED:
184 // sb.append("Possibly reparable, failed ");
187 // sb.append("Failed ");
190 // if (e.previousStatus() == Status.NONEXISTENT) {
191 // sb.append("addition");
193 // sb.append("modification");
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());
201 // System.out.flush();
211 Files
.delete(linkedDir
);
212 } catch (IOException e
) {
213 log
.error("Cannot remove " + linkedDir
);
217 public void setCmsState(CmsState cmsState
) {
218 this.cmsState
= cmsState
;
221 // public static void main(String[] args) throws Exception {
222 // Pipe inPipe = Pipe.open();
223 // Pipe outPipe = Pipe.open();
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));
232 // UnixDomainSocketAddress ioSocketAddress = JShellClient.ioSocketAddress();
233 // Files.deleteIfExists(ioSocketAddress.getPath());
235 // try (ServerSocketChannel serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX)) {
236 // serverChannel.bind(ioSocketAddress);
238 // try (SocketChannel channel = serverChannel.accept()) {
239 // new Thread(() -> {
242 // ByteBuffer buffer = ByteBuffer.allocate(1024);
244 // if (channel.read(buffer) < 0)
247 // inPipe.sink().write(buffer);
250 // } catch (IOException e) {
251 // e.printStackTrace();
253 // }, "Read in").start();
255 // new Thread(() -> {
258 // ByteBuffer buffer = ByteBuffer.allocate(1024);
260 // if (outPipe.source().read(buffer) < 0)
263 // channel.write(buffer);
266 // } catch (IOException e) {
267 // e.printStackTrace();
269 // }, "Write out").start();
274 // System.out.println("Completed");