1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.common;
22 import java.io.BufferedInputStream;
23 import java.io.BufferedOutputStream;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.BufferedReader;
28 import java.io.BufferedWriter;
29 import java.io.FileReader;
30 import java.io.FileWriter;
31 import org.apache.commons.collections.ExtendedProperties;
32
33 /**
34 * A bunch of utils
35 *
36 * @author Erich P. Gatejen
37 * @version 1.0
38 * <i>Version History</i>
39 * <code>EPG - Rewrite - 9Apr03
40 *
41 */
42 public class Utils {
43
44 // internal state values
45 private final static int STATE_FRESH = 0;
46 private final static int STATE_FRONT = 1;
47 private final static int STATE_READ = 2;
48 private final static int STATE_TAIL = 3;
49 // Again. I can't beleive I have to do this. This MAY break in future JDKs.
50 // It seems that BufferedReader.read() does NOT return -1 for an empty string; it
51 // returns the freaking 2scompliment of -1.
52 // (2003-May: This may work now. I'm too lazy to check it.)
53 private final static int MORONIC_TOP_VALUE = 65534;
54
55 /**
56 * Converts dot namespace to a path
57 * @param header prefix for the path
58 * @param dot path in dot notation
59 * @return a converted path
60 */
61 public static String dot2path(String header, String dot) {
62 return header
63 + AutohitProperties.literal_PATH_SEPERATOR
64 + dot.replace(
65 AutohitProperties.literal_NAME_SEPERATOR,
66 AutohitProperties.literal_PATH_SEPERATOR);
67 }
68
69 /**
70 * Make a file reference. If the file already exists, kill it.
71 * If the path doesn't exist, make it. It'll throw an exception if
72 * it fails.
73 * @param name path name
74 * @return file object
75 * @throws Exception
76 */
77 public static File makeFile(String name) throws Exception {
78
79 File dir;
80 String dirpath;
81 int last;
82
83 // construct the path
84 File target = new File(name);
85
86 if (target.exists()) {
87 target.delete();
88 } else {
89 // futz with the directory and make it is neccessary
90 last = name.lastIndexOf(AutohitProperties.literal_PATH_SEPERATOR);
91 if (last > 1) {
92 dirpath = name.substring(0, last);
93 dir = new File(dirpath);
94 if (!dir.exists()) {
95 dir.mkdirs();
96 }
97 }
98 }
99 return target;
100 }
101
102 /**
103 * Test and get property. Return null if not found or something went wrong.
104 * Traps all exceptions
105 * @param key key for the property
106 * @param props the property set
107 * @return the property object
108 */
109 public static Object testGetProperty(
110 String key,
111 ExtendedProperties props) {
112 Object thing = null;
113 try {
114 thing = props.getProperty(key);
115 } catch (Exception e) {
116 thing = null;
117 }
118 return thing;
119 }
120
121 /**
122 * Test and get property for truth. If will return true if the property
123 * containts 'true', otherwise it will return false;
124 * Traps all exceptions
125 * @param key key for the property
126 * @param props the property set
127 * @return true if the proprerty is 'true', otherwise false.
128 */
129 public static boolean testGetPropertyTruth(
130 String key,
131 ExtendedProperties props) {
132 boolean thing = false;
133 String thang;
134 try {
135 thang = (String)props.getProperty(key);
136 thing = thang.equals(Constants.TRUE);
137 } catch (Exception e) {
138 }
139 return thing;
140 }
141
142 /**
143 * Copy files. I can't believe I have to write this. It will always
144 * overwrite an existing file.
145 * @param source source file path
146 * @param dest destination file path
147 * @return string containing errors or messages
148 */
149 public static String copy(String source, String dest) {
150
151 String overwrite = " ";
152
153 BufferedOutputStream bos = null;
154 try {
155
156 File destf = new File(dest);
157 if (destf.exists()) {
158 destf.delete();
159 overwrite = " [overwrite] ";
160 }
161
162 byte[] buf = new byte[1024];
163 int sbuf;
164
165 BufferedInputStream bis =
166 new BufferedInputStream(new FileInputStream(source));
167 bos = new BufferedOutputStream(new FileOutputStream(dest));
168
169 sbuf = bis.read(buf, 0, 1024);
170 while (sbuf > 0) {
171 bos.write(buf, 0, sbuf);
172 sbuf = bis.read(buf, 0, 1024);
173 }
174 } catch (Exception e) {
175 }
176 try {
177 bos.close();
178 } catch (Exception e) {
179 return "Copy failed for=" + source + Constants.CRUDE_SEPERATOR;
180 }
181 return "Copied file=" + source + overwrite + Constants.CRUDE_SEPERATOR;
182 }
183
184 /**
185 * Merge a file with properties. It will overwrite an existing file.
186 * This is not exactly FAST.
187 * @param source source file
188 * @param dest destination file
189 * @param props properties that are candidates for substitution
190 * @return string containing errors or messages
191 */
192 public static String merge(
193 String source,
194 String dest,
195 ExtendedProperties props) {
196
197 int state = STATE_FRESH;
198 BufferedReader inBR = null;
199 BufferedWriter outT = null;
200 int workingC;
201 StringBuffer cBuf = null;
202 String theVar = null;
203 String ts = null;
204 StringBuffer messages = new StringBuffer();
205 String overwrite = " ";
206
207 // Read and fix
208 try {
209 // Clear an existing file
210 File destf = new File(dest);
211 if (destf.exists()) {
212 destf.delete();
213 overwrite = " [overwrite] ";
214 }
215 inBR = new BufferedReader(new FileReader(source));
216 outT = new BufferedWriter(new FileWriter(dest));
217
218 // start the engine
219 workingC = inBR.read();
220 while ((workingC >= 0)
221 && (workingC
222 < MORONIC_TOP_VALUE)) {
223
224 switch (state) {
225
226 case STATE_FRESH :
227 if (workingC == Constants.CONFIG_OPEN)
228 state = STATE_FRONT;
229 else
230 outT.write(workingC);
231 break;
232
233 case STATE_FRONT :
234 if (workingC == Constants.CONFIG_OPEN) {
235 state = STATE_READ;
236 cBuf = new StringBuffer();
237 } else {
238 state = STATE_FRESH;
239 outT.write(Constants.CONFIG_OPEN);
240 outT.write(workingC);
241 }
242 break;
243
244 case STATE_READ :
245 if (workingC == Constants.CONFIG_CLOSE) {
246 state = STATE_TAIL;
247 } else {
248 cBuf.append((char) workingC);
249 }
250 break;
251
252 case STATE_TAIL :
253 if (workingC == Constants.CONFIG_CLOSE) {
254 state = STATE_FRESH;
255 theVar = cBuf.toString();
256
257 if (props.containsKey(theVar)) {
258 ts = (String) props.get(theVar);
259 outT.write(ts, 0, ts.length());
260 } else {
261 outT.write(Constants.CONFIG_BLANK);
262 }
263 } else {
264 outT.write(Constants.CONFIG_CLOSE);
265 outT.write(workingC);
266 }
267 break;
268 } // end case
269 workingC = inBR.read();
270 }
271 } catch (Exception e) {
272 // Might just be EOF
273 //System.out.println(e);
274 } finally {
275 try {
276 inBR.close();
277 outT.close();
278 if (state != STATE_FRESH) {
279 messages.append(
280 "Bad File. Incomplete escape <<>> in file="
281 + source + Constants.CRUDE_SEPERATOR);
282 messages.append("......... Destination file might be corrupt. file=" + dest + Constants.CRUDE_SEPERATOR);
283 }
284 messages.append("Merged file to=" + dest + overwrite + Constants.CRUDE_SEPERATOR);
285 } catch (Exception e) {
286 messages.append("Catastrophic error merging" + source + Constants.CRUDE_SEPERATOR);
287 messages.append("......... Destination file might be corrupt. file=" + dest + Constants.CRUDE_SEPERATOR);
288 }
289
290 }
291 return messages.toString();
292 }
293
294 /**
295 * Copy entire directories. I can't believe I have to write this.
296 * @param source source is the source directory, without a training slash
297 * @param dest destination is the destination directory, without a training slash
298 * @param wipe destructive copy. If true, it will destroy destination directories before
299 * copying the files. The files themselves are always overwritten.
300 * @return string containing errors or messages
301 */
302 public static String copyDir(String source, String dest, boolean wipe) {
303
304 String[] directory;
305 String destinationfile = "";
306 String sourcefile;
307 File fsource = new File(source);
308 File fdest = new File(dest);
309 int size;
310 StringBuffer messages = new StringBuffer();
311
312 try {
313
314 // get the source directory list
315 directory = fsource.list();
316
317 // create the destination directory. If it already exists, wipe it.
318 if (fdest.exists()) {
319 if (wipe == true) {
320 messages.append(Utils.wipeDir(dest));
321 fdest.mkdirs();
322 messages.append(
323 "Make directory=" + dest + Constants.CRUDE_SEPERATOR);
324 }
325 } else {
326 fdest.mkdirs();
327 messages.append(
328 "Make directory=" + dest + Constants.CRUDE_SEPERATOR);
329 }
330
331 // rove the directory list
332 for (int i = 0; i < directory.length; i++) {
333 try {
334 destinationfile = dest + '/' + directory[i];
335 sourcefile = source + '/' + directory[i];
336 fsource = new File(sourcefile);
337 if (fsource.isDirectory()) {
338 messages.append(
339 "Is directory="
340 + sourcefile
341 + Constants.CRUDE_SEPERATOR);
342 messages.append(
343 Utils.copyDir(sourcefile, destinationfile, wipe));
344 } else {
345 messages.append(
346 Utils.copy(sourcefile, destinationfile));
347 }
348 } catch (Exception e) {
349 messages.append(
350 "Error on="
351 + destinationfile
352 + Constants.CRUDE_SEPERATOR);
353 }
354 }
355 messages.append(
356 "Done with directory= " + source + Constants.CRUDE_SEPERATOR);
357
358 } catch (Exception e) {
359 messages.append(
360 "Serious error on="
361 + dest
362 + " error="
363 + e.getMessage()
364 + Constants.CRUDE_SEPERATOR);
365 }
366 return messages.toString();
367 }
368
369 /**
370 * Wipe a directory and everything in it
371 * @param dest path to the directory
372 * @return string containing errors or messages
373 */
374 public static String wipeDir(String dest) {
375
376 String[] directory;
377 File fsource = new File(dest);
378 StringBuffer messages = new StringBuffer();
379 String newdest;
380 File newf;
381
382 try {
383
384 // get the source directory list
385 directory = fsource.list();
386
387 // rove the directory list
388 for (int i = 0; i < directory.length; i++) {
389 try {
390 newdest = dest + '/' + directory[i];
391 newf = new File(newdest);
392 if (newf.isDirectory()) {
393 messages.append(
394 "Wipe directory="
395 + newdest
396 + Constants.CRUDE_SEPERATOR);
397 messages.append(Utils.wipeDir(newdest));
398 } else {
399 newf.delete();
400 }
401 } catch (Exception e) {
402 messages.append(
403 "Error on wipe=" + dest + Constants.CRUDE_SEPERATOR);
404 }
405 }
406 fsource.delete();
407 messages.append(
408 "Done wipe of directory= " + dest + Constants.CRUDE_SEPERATOR);
409
410 } catch (Exception e) {
411 messages.append(
412 "Serious error on wipe of= "
413 + dest
414 + " error="
415 + e.getMessage()
416 + Constants.CRUDE_SEPERATOR);
417 }
418 return messages.toString();
419 }
420
421 /**
422 * Read a file into a String.
423 * @param f File to read
424 * @return string if successful or otherwise null
425 */
426 public static String loadFile2String(File f) {
427
428 StringBuffer buffer = new StringBuffer();
429 try {
430
431 char[] buf = new char[1024];
432 int sbuf;
433
434 BufferedReader bis
435 = new BufferedReader(new FileReader(f));
436
437 sbuf = bis.read(buf, 0, 1024);
438 while (sbuf > 0) {
439 buffer.append(buf, 0, sbuf);
440 sbuf = bis.read(buf, 0, 1024);
441 }
442 } catch (Exception e) {
443 e.printStackTrace();
444 return null;
445 }
446 return buffer.toString();
447 }
448
449 /**
450 * Get a packed, big-endian integer. The array better have 4 bytes or you'll get an exception
451 * @param buf arracy of bytes
452 * @return the integer
453 */
454 public static int packInteger(byte[] buf) {
455 return ((buf[3] & 0xFF) << 0) +
456 ((buf[2] & 0xFF) << 8) +
457 ((buf[1] & 0xFF) << 16) +
458 ((buf[0] & 0xFF) << 24);
459 }
460
461 /**
462 * Unpack an integer into an array--big-endian. The array better have 4 bytes or you'll get an exception
463 * @param buf array of bytes. better be at least 4 bytes
464 * @param offset offset into the array to start the unpack
465 * @param value the integer to unpack
466 */
467 public static void unpackInteger(byte[] buf, int offset, int value) {
468 buf[offset + 3] = (byte) (value >>> 0);
469 buf[offset + 2] = (byte) (value >>> 8);
470 buf[offset + 1] = (byte) (value >>> 16);
471 buf[offset + 0] = (byte) (value >>> 24);
472 }
473
474 // Total kludge. don't use
475 public static String norfIt(int value) {
476 if (value < 10) {
477 return new String ("0" + value);
478 } else if (value < 100) {
479 return Integer.toString(value);
480 } else if (value < 385) {
481 StringBuffer zonk = new StringBuffer();
482 zonk.append((char)value / 65);
483 zonk.append((char)value % 65);
484 return zonk.toString();
485 } else {
486 return "xx";
487 }
488 }
489
490 }
|