]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.jshell/src/org/argeo/cms/jshell/SocketPipeMirror.java
Functionally complete JShell
[lgpl/argeo-commons.git] / org.argeo.cms.jshell / src / org / argeo / cms / jshell / SocketPipeMirror.java
1 package org.argeo.cms.jshell;
2
3 import java.io.Closeable;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.nio.ByteBuffer;
8 import java.nio.channels.AsynchronousCloseException;
9 import java.nio.channels.Channels;
10 import java.nio.channels.Pipe;
11 import java.nio.channels.SocketChannel;
12
13 class SocketPipeMirror implements Closeable {
14 private final Pipe inPipe;
15 private final Pipe outPipe;
16
17 private final InputStream in;
18 private final OutputStream out;
19
20 private Thread readInThread;
21 private Thread writeOutThread;
22
23 private final String id;
24
25 public SocketPipeMirror(String id) throws IOException {
26 this.id = id;
27 inPipe = Pipe.open();
28 outPipe = Pipe.open();
29 in = Channels.newInputStream(inPipe.source());
30 out = Channels.newOutputStream(outPipe.sink());
31 }
32
33 public void open(SocketChannel channel) {
34 readInThread = new Thread(() -> {
35
36 try {
37 ByteBuffer buffer = ByteBuffer.allocate(1024);
38 while (!readInThread.isInterrupted() && channel.isConnected()) {
39 if (channel.read(buffer) < 0)
40 break;
41 buffer.flip();
42 inPipe.sink().write(buffer);
43 buffer.rewind();
44 }
45 } catch (AsynchronousCloseException e) {
46 // ignore
47 // TODO make it cleaner
48 } catch (IOException e) {
49 e.printStackTrace();
50 }
51 }, "JShell read " + id);
52 readInThread.start();
53
54 writeOutThread = new Thread(() -> {
55
56 try {
57 ByteBuffer buffer = ByteBuffer.allocate(1024);
58 while (!writeOutThread.isInterrupted() && channel.isConnected()) {
59 if (outPipe.source().read(buffer) < 0)
60 break;
61 buffer.flip();
62 channel.write(buffer);
63 buffer.rewind();
64 }
65 } catch (IOException e) {
66 e.printStackTrace();
67 }
68 }, "JShell write " + id);
69 writeOutThread.start();
70
71 }
72
73 @Override
74 public void close() throws IOException {
75 // TODO make it more robust
76 // readInThread.interrupt();
77 // writeOutThread.interrupt();
78 in.close();
79 out.close();
80 try {
81 readInThread.join();
82 } catch (InterruptedException e) {
83 // silent
84 }
85 try {
86 writeOutThread.join();
87 } catch (InterruptedException e) {
88 // silent
89 }
90 }
91
92 public InputStream getInputStream() {
93 return in;
94 }
95
96 public OutputStream getOutputStream() {
97 return out;
98 }
99 }