1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package mk.fsgrep.util;
26
27
28 import java.io.*;
29 import java.util.*;
30 import java.util.regex.*;
31
32 import mk.fsgrep.util.output.OutputDestination;
33
34
35 /***
36 * A utility for launching an external editor on a match file.
37 *
38 * @author Murali Krishnan
39 *
40 */
41 public abstract class ExternalEditor {
42
43
44
45
46 protected static ExternalEditor _instance = null;
47
48 protected static ExternalEditor UNDEFINED = new Undefined();
49
50 public static final String PERSISTENT_MAP_KEY = "external_editor";
51
52 private static final PersistentData pdata = PersistentData.getInstance();
53
54 public static final Pattern RE_FILE_NAME = Pattern.compile("%f");
55 public static final Pattern RE_LINE_NUM = Pattern.compile("%n");
56 public static final Pattern P_BACKSLASH = Pattern.compile("////");
57 public static final Pattern P_DOLLAR = Pattern.compile("//$");
58
59
60
61
62
63 public static synchronized ExternalEditor getInstance() {
64 ExternalEditor result = UNDEFINED;
65
66 if (_instance == null) {
67 String definition = lookupDefinition();
68 if (!"".equals(definition)) {
69 _instance = new Defined(definition);
70 result = _instance;
71 }
72 } else {
73 result = _instance;
74 }
75
76 return result;
77 }
78
79
80 public static void reset() {
81 _instance = null;
82 }
83
84
85 protected static String lookupDefinition() {
86 String result = "";
87
88 String candidate = pdata.getProperty(PERSISTENT_MAP_KEY);
89 if ((candidate != null)) {
90 result = candidate;
91 }
92
93 return result;
94 }
95
96
97 protected static String[] createCmdArray(String cmd) {
98 List<String> list = new ArrayList<String>();
99
100
101
102
103 boolean inDouble = false;
104 boolean inSingle = false;
105 StringBuffer buffer = new StringBuffer();
106 char[] charray = cmd.toCharArray();
107 for (char ch : charray) {
108 if (inDouble) {
109 if (ch == '\"') {
110 inDouble = false;
111 } else {
112 buffer.append(ch);
113 }
114 } else if (inSingle) {
115 if (ch == '\'') {
116 inSingle = false;
117 } else {
118 buffer.append(ch);
119 }
120 } else {
121 if (ch == '\"') {
122 inDouble = true;
123 } else if (ch == '\'') {
124 inSingle = true;
125 } else if (Character.isWhitespace(ch)) {
126 if (buffer.length() > 0) {
127 list.add(buffer.toString());
128 buffer.delete(0, buffer.length());
129 }
130 } else {
131 buffer.append(ch);
132 }
133 }
134 }
135
136 if (buffer.length() > 0) {
137 list.add(buffer.toString());
138 }
139
140 String[] result = list.toArray(new String[0]);
141
142 return result;
143 }
144
145
146
147
148
149 private String _spec = "";
150
151
152
153
154
155 ExternalEditor(String string) {
156 _spec = string;
157 }
158
159
160
161
162
163 protected String getSpec() {return _spec;}
164
165
166
167
168
169
170
171
172
173
174 protected String createCommand(String filename, String linenum) {
175 String result = getSpec();
176
177
178
179 Matcher matcher = RE_FILE_NAME.matcher(getSpec());
180 if (matcher.find()) {
181
182
183 String processed = P_BACKSLASH.matcher(filename).replaceAll("////////");
184 processed = P_DOLLAR.matcher(processed).replaceAll("//////$");
185 result = matcher.replaceAll(processed);
186 } else {
187 result += " " + filename;
188 }
189
190
191 result = RE_LINE_NUM.matcher(result).replaceAll(linenum);
192
193 return result;
194 }
195
196
197
198
199
200 public String toString() {
201 String result = "ExternalEditor[" + (isDefined()?getSpec():"UNDEFINED") + "]";
202
203 return result;
204 }
205
206
207 public void launch(String filename, String linenum, OutputDestination pStatus, OutputDestination pError) {
208 System.err.println("Launch capability is undefined.");
209 }
210
211
212
213
214
215 public boolean isDefined() {return true;}
216
217
218
219
220
221 static class Undefined extends ExternalEditor {
222 Undefined() {super("");}
223 public boolean isDefined() {return false;}
224 }
225
226 static class Defined extends ExternalEditor {
227 Defined(String string) {super(string);}
228
229
230 public void launch(String filename, String linenum, OutputDestination pStatus, OutputDestination pError) {
231 String cmd = createCommand(filename, linenum);
232 String[] cmdarray = createCmdArray(cmd);
233
234
235
236
237 pStatus.print("Launching [" + cmd + "]");
238 Runtime runtime = Runtime.getRuntime();
239 try {
240
241 Process process = runtime.exec(cmdarray);
242
243 } catch (IOException ioe) {
244 System.err.println("Could not exec [" + cmd + "].");
245 ioe.printStackTrace();
246 pError.print("Could not exec:\n" + cmd);
247 }
248 }
249 }
250
251
252
253
254
255
256
257 }