Source code: javatools/util/ScriptCatcher.java
1 /*
2 * ScriptCatcher.java
3 *
4 * Created on 24 dicembre 2001, 18.24
5 Javatools (modified version) - Some useful general classes.
6 Copyright (C) 2002-2003 Chris Bitmead (original) Antonio Petrelli (modified)
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 Contact me at: brenmcguire@users.sourceforge.net
23 */
24
25 package javatools.util;
26
27 import java.lang.*;
28 import java.io.*;
29 import java.util.*;
30
31 /** It's a class to catch text from a script file and to divide it into commands.
32 *
33 * @author Antonio Petrelli
34 * @version 0.1.10
35 */
36 public class ScriptCatcher {
37
38 /** Creates new ScriptCatcher */
39 public ScriptCatcher() {
40 commandText = new ArrayList();
41 divideCommandChar = ';';
42 stringDelimiterChar = new Character('\'');
43 commentDelimiter = "--";
44 removeFormat = true;
45 }
46
47 /** Controls whether formatting items (spaces and new-lines) are going to be
48 * removed.
49 * @param value <CODE>true</CODE>: formatting items will be removed;
50 * <CODE>false</CODE>: formatting items will NOT be removed.
51 */
52 public void setRemoveFormat(boolean value) {
53 removeFormat = value;
54 }
55
56 /** Returns the property about removing formatting items (spaces and new-lines)
57 * @return <CODE>true</CODE>: formatting items will be removed;
58 * <CODE>false</CODE>: formatting items will NOT be removed.
59 */
60 public boolean getRemoveFormat() {
61 return removeFormat;
62 }
63
64 /** Loads a script whose path is in "fileName" string, divides it into commands and make them available.
65 *
66 * @param fileName Path to the file to be processed.
67 * @throws FileNotFoundException If "fileName" is not found
68 */
69 public void loadScript(java.lang.String fileName) throws FileNotFoundException {
70 String tempBuf;
71
72 try {
73 tempBuf = textFile2String(fileName);
74 }
75 catch (FileNotFoundException e) {
76 throw e;
77 }
78 tempBuf = this.removeComments(tempBuf);
79 //ConstructCommands(tempBuf);
80 constructCommands(tempBuf);
81 }
82
83 public void loadScript(InputStream is) throws IOException {
84 String tempBuf;
85
86 tempBuf = inputStream2String(is);
87 tempBuf = this.removeComments(tempBuf);
88 //ConstructCommands(tempBuf);
89 constructCommands(tempBuf);
90 }
91
92 /** Saves a script using saved command texts into "fileName".
93 *
94 * @param fileName Path to file to be saved.
95 * @throws IOException If some I/O error occurs
96 */
97 public void saveScript(String fileName) throws IOException {
98 File outFile;
99 FileWriter out;
100 BufferedWriter outBuf;
101 Iterator commandIt;
102 char tempChars[];
103 int i, numComm;
104
105 outFile = new File(fileName);
106 try {
107 outFile.createNewFile();
108 out = new FileWriter(outFile);
109 outBuf = new BufferedWriter(out);
110 commandIt = commandText.iterator();
111 while (commandIt.hasNext()) {
112 outBuf.write ((String) commandIt.next()+String.valueOf(divideCommandChar));
113 outBuf.newLine();
114 }
115 /* numComm = commandText.length;
116 for (i=0; i<numComm; i++) {
117 outBuf.write (commandText[i]+String.valueOf(divideCommandChar));
118 outBuf.newLine();
119 }*/
120 }
121 catch (IOException e) {
122 throw e;
123 }
124 outBuf.close();
125 }
126
127 /** Construct commands fromf a given string (textScript) instead of a file.
128 * @param textScript The string containing the script to be processed.
129 */
130 public void constructCommands(String textScript) {
131 LinkedList indList;
132 int i, numChars, status, numCommands, tempPos;
133 Integer pos;
134 char tempChar;
135 String tempCommandText[];
136 final int NORMAL_TEXT_STATUS = 0,
137 STRING_STATUS = 1;
138
139 numChars=textScript.length();
140 status=0;
141 numCommands=0;
142 indList = new LinkedList();
143 for (i=0; i<numChars; i++) {
144 tempChar=textScript.charAt(i);
145 if (tempChar==divideCommandChar) {
146 if (status == NORMAL_TEXT_STATUS) {
147 pos = new Integer (i);
148 indList.add(pos);
149 numCommands++;
150 }
151 }
152 else if (stringDelimiterChar != null && tempChar==stringDelimiterChar.charValue()) {
153 if (status == NORMAL_TEXT_STATUS)
154 status=STRING_STATUS;
155 else status = NORMAL_TEXT_STATUS;
156 }
157 }
158 tempCommandText = new String [numCommands];
159 tempPos=0;
160 for (i=0; i<numCommands; i++) {
161 pos = (Integer) indList.get(i);
162 tempCommandText[i]=textScript.substring(tempPos, pos.intValue());
163 tempPos=pos.intValue()+1;
164 }
165 commandText = new ArrayList();
166 if (removeFormat)
167 for (i=0; i<numCommands; i++)
168 commandText.add(removeSpaces(tempCommandText[i].trim()));
169 else
170 for (i=0; i < numCommands; i++)
171 commandText.add(tempCommandText[i].trim());
172 }
173
174 /** Removes unuseful spaces, tabs and CRs from a command.
175 * WARNING! The text has to be a command WITHOUT command delimiter (default ;)!
176 *
177 * @param cmdText String containing the command to be processed.
178 * @return A string "purged" of unuseful spaces.
179 */
180 public String removeSpaces(String cmdText) {
181 int status;
182 char tempChar;
183 int i, textLength;
184 StringBuffer tempCmd;
185 final int START_STATUS = 0,
186 GOT_SPACE_STATUS = 1,
187 GOT_PARENTHESES_STATUS = 2,
188 GOT_STRING_DELIMITER_STATUS = 3;
189
190 status = 0;
191 textLength = cmdText.length();
192 tempCmd = new StringBuffer(textLength);
193 for (i=0; i<textLength; i++) {
194 tempChar=cmdText.charAt(i);
195 switch (status) {
196 case START_STATUS:
197 if (tempChar == ' ' || tempChar == '\n' || tempChar == '\r' || tempChar == '\t') {
198 status = GOT_SPACE_STATUS;
199 }
200 else if (stringDelimiterChar != null &&
201 tempChar == stringDelimiterChar.charValue()) {
202 status = GOT_STRING_DELIMITER_STATUS;
203 tempCmd.append(tempChar);
204 }
205 else {
206 tempCmd.append(tempChar);
207 }
208 break;
209 case GOT_SPACE_STATUS:
210 if (tempChar == ' ' || tempChar == '\n' || tempChar == '\r' || tempChar == '\t') {
211 }
212 else if (tempChar == '(') {
213 tempCmd.append(" (");
214 status = GOT_PARENTHESES_STATUS;
215 }
216 else if (tempChar == ')') {
217 tempCmd.append(')');
218 status = START_STATUS;
219 }
220 else if (stringDelimiterChar != null &&
221 tempChar == stringDelimiterChar.charValue()) {
222 tempCmd.append(" "+tempChar);
223 status = GOT_STRING_DELIMITER_STATUS;
224 }
225 else {
226 tempCmd.append(" "+tempChar);
227 status = START_STATUS;
228 }
229 break;
230 case GOT_PARENTHESES_STATUS:
231 if (tempChar == ' ' || tempChar == '\n' || tempChar == '\r' || tempChar == '\t') {
232 }
233 else if (tempChar == '(') {
234 tempCmd.append('(');
235 }
236 else if (tempChar == ')') {
237 tempCmd.append(')');
238 status = START_STATUS;
239 }
240 else if (stringDelimiterChar != null &&
241 tempChar == stringDelimiterChar.charValue()) {
242 tempCmd.append(tempChar);
243 status = GOT_STRING_DELIMITER_STATUS;
244 }
245 else {
246 tempCmd.append(tempChar);
247 status = START_STATUS;
248 }
249 break;
250 case GOT_STRING_DELIMITER_STATUS:
251 if (tempChar == '\n' || tempChar == '\r' || tempChar == '\t') {
252 }
253 else if (stringDelimiterChar != null &&
254 tempChar == stringDelimiterChar.charValue()) {
255 tempCmd.append(tempChar);
256 status = START_STATUS;
257 }
258 else {
259 tempCmd.append(tempChar);
260 }
261 }
262 }
263 return tempCmd.toString();
264 }
265
266 /** Removes comments from a script (string inStr).
267 * @param inStr The string containing the string to be processed.
268 * @return A string which represents the script WITHOUT comments.
269 */
270 public String removeComments (String inStr) {
271 StringBuffer inStrBuf;
272 int posString, startIndex;
273 String tempString;
274 StringReader inStrReader;
275 BufferedReader stringGetter;
276 StringWriter outStrWriter;
277 BufferedWriter stringPutter;
278
279 if (commentDelimiter == null)
280 return inStr;
281
282 inStrBuf = new StringBuffer(inStr.length());
283 inStrReader = new StringReader(inStr);
284 stringGetter = new BufferedReader(inStrReader);
285 outStrWriter = new StringWriter();
286 stringPutter = new BufferedWriter(outStrWriter);
287 try {
288 tempString = stringGetter.readLine();
289 while (tempString != null) {
290 if (!tempString.equals(""))
291 stringPutter.write(removeOneComment(tempString));
292 stringPutter.newLine();
293 tempString = stringGetter.readLine();
294 }
295 stringPutter.flush();
296 }
297 catch (IOException e) {
298 System.out.println("Something weird happened, the string cannot be read!");
299 System.exit(1);
300 }
301 return outStrWriter.toString();
302 }
303
304 /** Removes all the commands.
305 */
306 public void clear() {
307 commandText.clear();
308 }
309
310 /** Returns the number of commands.
311 * @return Number of commands contained.
312 */
313 public int getNumCommands() {
314 return commandText.size();
315 }
316
317 /** Sets the number of commands. There's no need to use it if you are
318 * loading a script file or using a script string.
319 * You need it ONLY if you are going to give commands one by one.
320 * All previous saved commands will be erased.
321 *
322 * @param numCommands The number of commands to be generated.
323 * @throws IndexOutOfBoundsException if <CODE>numCommands</CODE> is less than 1.
324 */
325 public void setNumCommands (int numCommands) throws IndexOutOfBoundsException {
326 if (numCommands > 0)
327 commandText = new ArrayList(numCommands);
328 else
329 throw new IndexOutOfBoundsException();
330 }
331
332 /** Returns the command text of command <CODE>numCommand</CODE>.
333 * @param numCommand the number of the interested command, between <CODE>0</CODE> and <CODE>getNumCommands()-1</CODE>
334 * @throws IndexOutOfBoundsException If <CODE>numCommand</CODE> is not valid
335 * @return The needed command text.
336 */
337 public String getCommandText(int numCommand) throws IndexOutOfBoundsException {
338 if (numCommand >= 0 && numCommand < commandText.size())
339 return (String) commandText.get(numCommand);
340 else
341 throw new IndexOutOfBoundsException();
342 }
343
344 /** Returns the commands as an array.
345 * @return The commands as an array.
346 */
347 public String[] getCommands() {
348 String[] tempCommandText;
349
350 tempCommandText = new String[commandText.size()];
351 commandText.toArray(tempCommandText);
352 return tempCommandText;
353 }
354
355 /** Returns the commands as a list.
356 * @return The commands as a list.
357 */
358 public ArrayList getCommandList() {
359 return commandText;
360 }
361
362 /** Returns an iterator to iterate commands.
363 * @return The needed iterator.
364 */
365 public Iterator iterator() {
366 return commandText.iterator();
367 }
368
369 /** Adds a new command.
370 * @param value The command to add.
371 */
372 public void addCommand(String value) {
373 commandText.add(value);
374 }
375
376 /** Sets the text for command <CODE>numCommand</CODE> with the string <CODE>value</CODE>.
377 * @param numCommand The number of the interested command, between <CODE>0</CODE> and <CODE>getNumCommands()-1</CODE>.
378 * @param value The command text, WITHOUT command delimiter!
379 * @throws IndexOutOfBoundsException If numCommand is not valid.
380 */
381 public void setCommandText (int numCommand, String value) throws IndexOutOfBoundsException {
382 if (numCommand < commandText.size())
383 commandText.set(numCommand, value);
384 else
385 commandText.add(numCommand, value);
386 }
387
388 /** Sets the character who represents the end of a command.
389 * @param inChar The character which will be interpreted as a command delimiter.
390 */
391 public void setDivideCommandChar (char inChar) {
392 divideCommandChar = inChar;
393 }
394
395 /** Returns the character who represents the end of a command.
396 * @return The needed character.
397 */
398 public char getDivideCommandChar () {
399 return divideCommandChar;
400 }
401
402 /** Sets the character who represents the start/end of a string in the script.
403 * @param inChar The character which will be interpreted as a string delimiter.
404 */
405 public void setStringDelimiterChar (Character inChar) {
406 stringDelimiterChar = inChar;
407 }
408
409 /** Returns the character who represents the start/end of a string in the script.
410 * @return The needed character.
411 */
412 public Character getStringDelimiterChar () {
413 return stringDelimiterChar;
414 }
415
416 /** Sets the string who represents the start of a comment.
417 * @param inStr The string which will be interpreted as a comment delimiter.
418 */
419 public void setCommentDelimiter (String inStr) {
420 commentDelimiter = inStr;
421 }
422
423 /** Returns the string who represents the start of a comment.
424 * @return The needed string.
425 */
426 public String getCommentdelimiter () {
427 return commentDelimiter;
428 }
429
430 /** Loads text file "fileName" and puts its content into a string.
431 * @param fileName Path to file to be loaded.
432 * @throws FileNotFoundException If the file "fileName" is not found.
433 * @return The string representing the content of the text file.
434 */
435 public static String textFile2String(String fileName) throws FileNotFoundException {
436 File inFile;
437 FileReader in;
438 String tempBuf;
439 char tempChars[];
440
441 inFile = new File(fileName);
442 try {
443 in = new FileReader(inFile);
444 }
445 catch (FileNotFoundException e) {
446 throw e;
447 }
448 //ConstructCommands(tempBuf);
449 tempChars = new char [(int) inFile.length()];
450 try {
451 in.read(tempChars);
452 }
453 catch (IOException e) {
454 System.out.println("I/O Error");
455 System.exit(1);
456 }
457 tempBuf = new String (tempChars);
458 return tempBuf;
459 }
460
461 public static String inputStream2String(InputStream is) throws IOException {
462 InputStreamReader isreader;
463 BufferedReader reader;
464 StringWriter strWriter;
465 BufferedWriter writer;
466 String tempBuf, tempLine;
467
468 if (is != null) {
469 isreader = new InputStreamReader(is);
470 reader = new BufferedReader(isreader);
471 strWriter = new StringWriter();
472 writer = new BufferedWriter(strWriter);
473 tempLine = reader.readLine();
474 while (tempLine != null) {
475 writer.write(tempLine);
476 writer.newLine();
477 tempLine = reader.readLine();
478 }
479 writer.flush();
480 return strWriter.toString();
481 }
482 else
483 throw new IOException("InputStream null!");
484 }
485
486 private ArrayList commandText;
487 private char divideCommandChar;
488 private Character stringDelimiterChar;
489 private String commentDelimiter;
490 private boolean removeFormat;
491
492 private String removeOneComment (String tempString) {
493
494 int pos, posComm, posStringDelimiter, stringDelimiterCount;
495 String returnString;
496
497 pos = 0;
498 returnString = "";
499 do {
500 posComm = tempString.indexOf(commentDelimiter, pos);
501 if (posComm > 0) {
502 stringDelimiterCount = -1;
503 posStringDelimiter = 0;
504 if (stringDelimiterChar != null)
505 while (posStringDelimiter >= 0 && posStringDelimiter < posComm) {
506 posStringDelimiter = tempString.indexOf(stringDelimiterChar.charValue(),
507 posStringDelimiter);
508 stringDelimiterCount++;
509 }
510 if ((stringDelimiterCount % 2) == 0) {
511 returnString=tempString.substring(0, posComm-1);
512 posComm = -1;
513 }
514 }
515 else if (posComm == 0) {
516 returnString = "";
517 posComm = -1;
518 }
519 else {
520 returnString = tempString;
521 }
522 pos = posComm + commentDelimiter.length();
523 } while (posComm >= 0);
524 return returnString;
525 }
526 }