KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > util > CodeSwitcher


1 /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the Hypersonic SQL Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This software consists of voluntary contributions made by many individuals
31  * on behalf of the Hypersonic SQL Group.
32  *
33  *
34  * For work added by the HSQL Development Group:
35  *
36  * Copyright (c) 2001-2005, The HSQL Development Group
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions are met:
41  *
42  * Redistributions of source code must retain the above copyright notice, this
43  * list of conditions and the following disclaimer.
44  *
45  * Redistributions in binary form must reproduce the above copyright notice,
46  * this list of conditions and the following disclaimer in the documentation
47  * and/or other materials provided with the distribution.
48  *
49  * Neither the name of the HSQL Development Group nor the names of its
50  * contributors may be used to endorse or promote products derived from this
51  * software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
57  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */

65
66
67 package org.hsqldb.util;
68
69 import java.io.File JavaDoc;
70 import java.io.FileReader JavaDoc;
71 import java.io.FileWriter JavaDoc;
72 import java.io.IOException JavaDoc;
73 import java.io.LineNumberReader JavaDoc;
74 import java.util.Vector JavaDoc;
75
76 // fredt@users 20020315 - patch 1.7.0 - minor fixes
77
// changed line separator to System based value
78
// moved the Profile class to org.hsqldb.test package
79
// fredt@users 20021020 - patch 1.7.1 - formatting fix
80
// avoid moving blank lines which would be interpreted as code change by CVS
81
// fredt@users 20021118 - patch 1.7.2 - no-change, no-save fix
82
// if the file contents do not change, do not save a new version of file
83
// fredt@users 20040322 - removed unused profiling code
84

85 /**
86  * Modifies the source code to support different JDK or profile settings. <p>
87  * <pre>
88  * Usage: java CodeSwitcher [paths] [labels] [+][-]
89  * If no labels are specified then all used
90  * labels in the source code are shown.
91  * Use +MODE to switch on the things labeld MODE
92  * Use -MODE to switch off the things labeld MODE
93  * Path: Any number of path or files may be
94  * specified. Use . for the current directory
95  * (including sub-directories).
96  * Example: java CodeSwitcher +JAVA2 .
97  * This example switches on code labeled JAVA2
98  * in all *.java files in the current directory
99  * and all subdirectories.
100  * java CodeSwitcher + .
101  * Adds test code to the code.
102  * java CodeSwitcher - .
103  * Removes test code from the code
104  * </pre>
105  *
106  * @author Thomas Mueller (Hypersonic SQL Group)
107  * @version 1.7.0
108  * @since Hypersonic SQL
109  */

110 public class CodeSwitcher {
111
112     private static final String JavaDoc ls = System.getProperty("line.separator",
113         "\n");
114     private Vector JavaDoc vList;
115     private Vector JavaDoc vSwitchOn;
116     private Vector JavaDoc vSwitchOff;
117     private Vector JavaDoc vSwitches;
118     private static final int MAX_LINELENGTH = 82;
119
120     /**
121      * Method declaration
122      *
123      *
124      * @param a
125      */

126     public static void main(String JavaDoc[] a) {
127
128         CodeSwitcher s = new CodeSwitcher();
129
130         if (a.length == 0) {
131             showUsage();
132
133             return;
134         }
135
136         boolean path = false;
137
138         for (int i = 0; i < a.length; i++) {
139             String JavaDoc p = a[i];
140
141             if (p.startsWith("+")) {
142                 s.vSwitchOn.addElement(p.substring(1));
143             } else if (p.startsWith("-")) {
144                 s.vSwitchOff.addElement(p.substring(1));
145             } else {
146                 s.addDir(p);
147
148                 path = true;
149             }
150         }
151
152         if (!path) {
153             printError("no path specified");
154             showUsage();
155         }
156
157         s.process();
158
159         if (s.vSwitchOff.size() == 0 && s.vSwitchOn.size() == 0) {
160             s.printSwitches();
161         }
162     }
163
164     /**
165      * Method declaration
166      *
167      */

168     static void showUsage() {
169
170         System.out.print("Usage: java CodeSwitcher [paths] [labels] [+][-]\n"
171                          + "If no labels are specified then all used\n"
172                          + "labels in the source code are shown.\n"
173                          + "Use +MODE to switch on the things labeld MODE\n"
174                          + "Use -MODE to switch off the things labeld MODE\n"
175                          + "Path: Any number of path or files may be\n"
176                          + "specified. Use . for the current directory\n"
177                          + "(including sub-directories).\n"
178                          + "Example: java CodeSwitcher +JAVA2 .\n"
179                          + "This example switches on code labeled JAVA2\n"
180                          + "in all *.java files in the current directory\n"
181                          + "and all subdirectories.\n");
182     }
183
184     /**
185      * Constructor declaration
186      *
187      */

188     CodeSwitcher() {
189
190         vList = new Vector JavaDoc();
191         vSwitchOn = new Vector JavaDoc();
192         vSwitchOff = new Vector JavaDoc();
193         vSwitches = new Vector JavaDoc();
194     }
195
196     /**
197      * Method declaration
198      *
199      */

200     void process() {
201
202         int len = vList.size();
203
204         for (int i = 0; i < len; i++) {
205             System.out.print(".");
206
207             String JavaDoc file = (String JavaDoc) vList.elementAt(i);
208
209             if (!processFile(file)) {
210                 System.out.println("in file " + file + " !");
211             }
212         }
213
214         System.out.println("");
215     }
216
217     /**
218      * Method declaration
219      *
220      */

221     void printSwitches() {
222
223         System.out.println("Used labels:");
224
225         for (int i = 0; i < vSwitches.size(); i++) {
226             System.out.println((String JavaDoc) (vSwitches.elementAt(i)));
227         }
228     }
229
230     /**
231      * Method declaration
232      *
233      *
234      * @param path
235      */

236     void addDir(String JavaDoc path) {
237
238         File JavaDoc f = new File JavaDoc(path);
239
240         if (f.isFile() && path.endsWith(".java")) {
241             vList.addElement(path);
242         } else if (f.isDirectory()) {
243             String JavaDoc[] list = f.list();
244
245             for (int i = 0; i < list.length; i++) {
246                 addDir(path + File.separatorChar + list[i]);
247             }
248         }
249     }
250
251     /**
252      * Method declaration
253      *
254      *
255      * @param name
256      *
257      * @return
258      */

259     boolean processFile(String JavaDoc name) {
260
261         File JavaDoc f = new File JavaDoc(name);
262         File JavaDoc fnew = new File JavaDoc(name + ".new");
263         int state = 0; // 0=normal 1=inside_if 2=inside_else
264
boolean switchoff = false;
265         boolean working = false;
266
267         try {
268             Vector JavaDoc v = getFileLines(f);
269             Vector JavaDoc v1 = new Vector JavaDoc(v.size());
270
271             for (int i = 0; i < v.size(); i++) {
272                 v1.addElement(v.elementAt(i));
273             }
274
275             for (int i = 0; i < v.size(); i++) {
276                 String JavaDoc line = (String JavaDoc) v.elementAt(i);
277
278                 if (line == null) {
279                     break;
280                 }
281
282                 if (working) {
283                     if (line.equals("/*") || line.equals("*/")) {
284                         v.removeElementAt(i--);
285
286                         continue;
287                     }
288                 }
289
290                 if (line.startsWith("//#")) {
291                     if (line.startsWith("//#ifdef ")) {
292                         if (state != 0) {
293                             printError(
294                                 "'#ifdef' not allowed inside '#ifdef'");
295
296                             return false;
297                         }
298
299                         state = 1;
300
301                         String JavaDoc s = line.substring(9);
302
303                         if (vSwitchOn.indexOf(s) != -1) {
304                             working = true;
305                             switchoff = false;
306                         } else if (vSwitchOff.indexOf(s) != -1) {
307                             working = true;
308
309                             v.insertElementAt("/*", ++i);
310
311                             switchoff = true;
312                         }
313
314                         if (vSwitches.indexOf(s) == -1) {
315                             vSwitches.addElement(s);
316                         }
317                     } else if (line.startsWith("//#else")) {
318                         if (state != 1) {
319                             printError("'#else' without '#ifdef'");
320
321                             return false;
322                         }
323
324                         state = 2;
325
326                         if (!working) {}
327                         else if (switchoff) {
328                             if (v.elementAt(i - 1).equals("")) {
329                                 v.insertElementAt("*/", i - 1);
330
331                                 i++;
332                             } else {
333                                 v.insertElementAt("*/", i++);
334                             }
335
336                             switchoff = false;
337                         } else {
338                             v.insertElementAt("/*", ++i);
339
340                             switchoff = true;
341                         }
342                     } else if (line.startsWith("//#endif")) {
343                         if (state == 0) {
344                             printError("'#endif' without '#ifdef'");
345
346                             return false;
347                         }
348
349                         state = 0;
350
351                         if (working && switchoff) {
352                             if (v.elementAt(i - 1).equals("")) {
353                                 v.insertElementAt("*/", i - 1);
354
355                                 i++;
356                             } else {
357                                 v.insertElementAt("*/", i++);
358                             }
359                         }
360
361                         working = false;
362                     } else {}
363                 }
364             }
365
366             if (state != 0) {
367                 printError("'#endif' missing");
368
369                 return false;
370             }
371
372             boolean filechanged = false;
373
374             for (int i = 0; i < v.size(); i++) {
375                 if (!v1.elementAt(i).equals(v.elementAt(i))) {
376                     filechanged = true;
377
378                     break;
379                 }
380             }
381
382             if (!filechanged) {
383                 return true;
384             }
385
386             writeFileLines(v, fnew);
387
388             File JavaDoc fbak = new File JavaDoc(name + ".bak");
389
390             fbak.delete();
391             f.renameTo(fbak);
392
393             File JavaDoc fcopy = new File JavaDoc(name);
394
395             fnew.renameTo(fcopy);
396             fbak.delete();
397
398             return true;
399         } catch (Exception JavaDoc e) {
400             printError(e.toString());
401
402             return false;
403         }
404     }
405
406     static Vector JavaDoc getFileLines(File JavaDoc f) throws IOException JavaDoc {
407
408         LineNumberReader JavaDoc read = new LineNumberReader JavaDoc(new FileReader JavaDoc(f));
409         Vector JavaDoc v = new Vector JavaDoc();
410
411         for (;;) {
412             String JavaDoc line = read.readLine();
413
414             if (line == null) {
415                 break;
416             }
417
418             v.addElement(line);
419         }
420
421         read.close();
422
423         return v;
424     }
425
426     static void writeFileLines(Vector JavaDoc v, File JavaDoc f) throws IOException JavaDoc {
427
428         FileWriter JavaDoc write = new FileWriter JavaDoc(f);
429
430         for (int i = 0; i < v.size(); i++) {
431             write.write((String JavaDoc) v.elementAt(i));
432             write.write(ls);
433         }
434
435         write.flush();
436         write.close();
437     }
438
439     /**
440      * Method declaration
441      *
442      *
443      * @param error
444      */

445     static void printError(String JavaDoc error) {
446         System.out.println("");
447         System.out.println("ERROR: " + error);
448     }
449 }
450
Popular Tags