1 /*
2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.io.BufferedInputStream;
25 import java.io.BufferedOutputStream;
26 import java.io.DataInputStream;
27 import java.io.DataOutputStream;
28 import java.io.IOException;
29 import java.io.StringWriter;
30 import java.net.Socket;
31 import java.nio.charset.StandardCharsets;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.util.Collections;
36 
37 public class CustomEditor implements AutoCloseable {
38 
39     public static final int SOURCE_CODE = 0;
40     public static final int GET_SOURCE_CODE = 1;
41     public static final int REMOVE_CODE = 2;
42     public static final int GET_FILENAME = 3;
43 
44     public static final int EXIT_CODE = -1;
45     public static final int ACCEPT_CODE = -2;
46     public static final int CANCEL_CODE = -3;
47 
48     private final Socket socket;
49     private final Path path;
50     private final StringWriter writer;
51     private final String source;
52 
CustomEditor(int port, String fileName)53     public CustomEditor(int port, String fileName) throws IOException {
54         this.socket = new Socket((String) null, port);
55         this.path = Paths.get(fileName);
56         this.writer = new StringWriter();
57         this.source = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
58     }
59 
loop()60     public void loop() throws IOException {
61         DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
62         DataOutputStream output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
63 
64         while (true) {
65             int cmd = input.readInt();
66             switch (cmd) {
67                 case EXIT_CODE: {
68                     Files.write(path, Collections.singletonList(writer.toString()));
69                     return;
70                 }
71                 case GET_SOURCE_CODE: {
72                     writeString(output, source);
73                     break;
74                 }
75                 case REMOVE_CODE: {
76                     // only for external editor
77                     Files.delete(path);
78                     break;
79                 }
80                 case GET_FILENAME: {
81                     writeString(output, path.toString());
82                     break;
83                 }
84                 case CANCEL_CODE: {
85                     return;
86                 }
87                 case ACCEPT_CODE: {
88                     Files.write(path, Collections.singletonList(writer.toString()));
89                     break;
90                 }
91                 case SOURCE_CODE: {
92                     int length = input.readInt();
93                     byte[] bytes = new byte[length];
94                     input.readFully(bytes);
95                     writer.write(new String(bytes, StandardCharsets.UTF_8));
96                     break;
97                 }
98             }
99         }
100     }
101 
writeString(DataOutputStream output, String s)102     private void writeString(DataOutputStream output, String s) throws IOException {
103         byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
104         output.writeInt(bytes.length);
105         output.write(bytes);
106         output.flush();
107     }
108 
main(String[] args)109     public static void main(String[] args) throws IOException {
110         if (args.length != 2) {
111             System.err.println("Usage: port file");
112             System.exit(1);
113         }
114         try (CustomEditor editor = new CustomEditor(Integer.parseInt(args[0]), args[1])) {
115             editor.loop();
116         }
117     }
118 
119     @Override
close()120     public void close() throws IOException {
121         socket.close();
122     }
123 }
124