Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/hsqldb/util/CodeSwitcher.java


1   /* Copyrights and Licenses
2    *
3    * This product includes Hypersonic SQL.
4    * Originally developed by Thomas Mueller and the Hypersonic SQL Group. 
5    *
6    * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. 
7    * Redistribution and use in source and binary forms, with or without modification, are permitted
8    * provided that the following conditions are met: 
9    *     -  Redistributions of source code must retain the above copyright notice, this list of conditions
10   *         and the following disclaimer. 
11   *     -  Redistributions in binary form must reproduce the above copyright notice, this list of
12   *         conditions and the following disclaimer in the documentation and/or other materials
13   *         provided with the distribution. 
14   *     -  All advertising materials mentioning features or use of this software must display the
15   *        following acknowledgment: "This product includes Hypersonic SQL." 
16   *     -  Products derived from this software may not be called "Hypersonic SQL" nor may
17   *        "Hypersonic SQL" appear in their names without prior written permission of the
18   *         Hypersonic SQL Group. 
19   *     -  Redistributions of any form whatsoever must retain the following acknowledgment: "This
20   *          product includes Hypersonic SQL." 
21   * This software is provided "as is" and any expressed or implied warranties, including, but
22   * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23   * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24   * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25   * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26   * or business interruption). However caused any on any theory of liability, whether in contract,
27   * strict liability, or tort (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   * This software consists of voluntary contributions made by many individuals on behalf of the
30   * Hypersonic SQL Group.
31   *
32   *
33   * For work added by the HSQL Development Group:
34   *
35   * Copyright (c) 2001-2002, The HSQL Development Group
36   * All rights reserved.
37   *
38   * Redistribution and use in source and binary forms, with or without
39   * modification, are permitted provided that the following conditions are met:
40   *
41   * Redistributions of source code must retain the above copyright notice, this
42   * list of conditions and the following disclaimer, including earlier
43   * license statements (above) and comply with all above license conditions.
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, including earlier
48   * license statements (above) and comply with all above license conditions.
49   *
50   * Neither the name of the HSQL Development Group nor the names of its
51   * contributors may be used to endorse or promote products derived from this
52   * software without specific prior written permission.
53   *
54   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57   * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
58   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
59   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
60   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65   */
66  
67  
68  package org.hsqldb.util;
69  
70  import java.io.*;
71  import java.util.*;
72  
73  // fredt@users 20020315 - patch 1.7.0 - minor fixes
74  // changed line separator to System based value
75  // moved the Profile class to org.hsqldb.test package
76  // fredt@users 20021020 - patch 1.7.1 - formatting fix
77  // avoid moving blank lines which would be interpreted as code change by CVS
78  
79  /**
80   * Modifies the source code to support different JDK or profile settings. <p>
81   * <pre>
82   * Usage: java CodeSwitcher [paths] [labels] [+][-]
83   * If no labels are specified then all used
84   * labels in the source code are shown.
85   * Use +MODE to switch on the things labeld MODE
86   * Use -MODE to switch off the things labeld MODE
87   * Path: Any number of path or files may be
88   * specified. Use . for the current directory
89   * (including sub-directories).
90   * Example: java CodeSwitcher +JAVA2 .
91   * This example switches on code labeled JAVA2
92   * in all *.java files in the current directory
93   * and all subdirectories.
94   * java CodeSwitcher + .
95   * Adds test code to the code.
96   * java CodeSwitcher - .
97   * Removes test code from the code
98   * </pre>
99   *
100  * @version 1.7.0
101  */
102 public class CodeSwitcher {
103 
104     private static final String ls = System.getProperty("line.separator",
105         "\n");
106     private Vector           vList;
107     private Vector           vSwitchOn;
108     private Vector           vSwitchOff;
109     private Vector           vSwitches;
110     private boolean          bAdd, bRemove;
111     private static final int MAX_LINELENGTH = 82;
112 
113     /**
114      * Method declaration
115      *
116      *
117      * @param a
118      */
119     public static void main(String a[]) {
120 
121         CodeSwitcher s = new CodeSwitcher();
122 
123         if (a.length == 0) {
124             showUsage();
125 
126             return;
127         }
128 
129         boolean path = false;
130 
131         for (int i = 0; i < a.length; i++) {
132             String p = a[i];
133 
134             if (p.startsWith("+")) {
135                 if (p.length() == 1) {
136                     s.bAdd = true;
137                 } else {
138                     s.vSwitchOn.addElement(p.substring(1));
139                 }
140             } else if (p.startsWith("-")) {
141                 if (p.length() == 1) {
142                     s.bRemove = true;
143                 } else {
144                     s.vSwitchOff.addElement(p.substring(1));
145                 }
146             } else {
147                 s.addDir(p);
148 
149                 path = true;
150             }
151         }
152 
153         if (!path) {
154             printError("no path specified");
155             showUsage();
156         }
157 
158         s.process();
159 
160         if (s.vSwitchOff.size() == 0 && s.vSwitchOn.size() == 0) {
161             s.printSwitches();
162         }
163     }
164 
165     /**
166      * Method declaration
167      *
168      */
169     static void showUsage() {
170 
171         System.out.print("Usage: java CodeSwitcher [paths] [labels] [+][-]\n"
172                          + "If no labels are specified then all used\n"
173                          + "labels in the source code are shown.\n"
174                          + "Use +MODE to switch on the things labeld MODE\n"
175                          + "Use -MODE to switch off the things labeld MODE\n"
176                          + "Path: Any number of path or files may be\n"
177                          + "specified. Use . for the current directory\n"
178                          + "(including sub-directories).\n"
179                          + "Example: java CodeSwitcher +JAVA2 .\n"
180                          + "This example switches on code labeled JAVA2\n"
181                          + "in all *.java files in the current directory\n"
182                          + "and all subdirectories.\n"
183                          + "java CodeSwitcher + .\n"
184                          + "Adds test code to the code.\n"
185                          + "java CodeSwitcher - .\n"
186                          + "Removed test code from the code.\n");
187     }
188 
189     /**
190      * Constructor declaration
191      *
192      */
193     CodeSwitcher() {
194 
195         vList      = new Vector();
196         vSwitchOn  = new Vector();
197         vSwitchOff = new Vector();
198         vSwitches  = new Vector();
199     }
200 
201     /**
202      * Method declaration
203      *
204      */
205     void process() {
206 
207         int len = vList.size();
208 
209         for (int i = 0; i < len; i++) {
210             System.out.print(".");
211 
212             String file = (String) vList.elementAt(i);
213 
214             if (bAdd || bRemove) {
215                 int maxlen = testFile(file);
216 
217                 if (bAdd &&!bRemove) {
218                     addTest(file, maxlen);
219                 } else {
220                     removeTest(file);
221                 }
222             } else {
223                 if (!processFile(file)) {
224                     System.out.println("in file " + file + " !");
225                 }
226             }
227         }
228 
229         System.out.println("");
230     }
231 
232     /**
233      * Method declaration
234      *
235      */
236     void printSwitches() {
237 
238         System.out.println("Used labels:");
239 
240         for (int i = 0; i < vSwitches.size(); i++) {
241             System.out.println((String) (vSwitches.elementAt(i)));
242         }
243     }
244 
245     /**
246      * Method declaration
247      *
248      *
249      * @param path
250      */
251     void addDir(String path) {
252 
253         File f = new File(path);
254 
255         if (f.isFile() && path.endsWith(".java")) {
256             vList.addElement(path);
257         } else if (f.isDirectory()) {
258             String list[] = f.list();
259 
260             for (int i = 0; i < list.length; i++) {
261                 addDir(path + File.separatorChar + list[i]);
262             }
263         }
264     }
265 
266     /**
267      * Method declaration
268      *
269      *
270      * @param name
271      */
272     void removeTest(String name) {
273 
274         File f    = new File(name);
275         File fnew = new File(name + ".new");
276 
277         try {
278             LineNumberReader read  = new LineNumberReader(new FileReader(f));
279             FileWriter       write = new FileWriter(fnew);
280 
281             while (true) {
282                 String line = read.readLine();
283 
284                 if (line == null) {
285                     break;
286                 }
287 
288                 if (line.startsWith("Profile.visit(")) {
289                     int s = line.indexOf(';');
290 
291                     line = line.substring(s + 1);
292                 }
293 
294                 write.write(line + ls);
295             }
296 
297             read.close();
298             write.flush();
299             write.close();
300 
301             File fbak = new File(name + ".bak");
302 
303             fbak.delete();
304             f.renameTo(fbak);
305 
306             File fcopy = new File(name);
307 
308             fnew.renameTo(fcopy);
309             fbak.delete();
310         } catch (Exception e) {
311             printError(e.getMessage());
312         }
313     }
314 
315     /**
316      * Method declaration
317      *
318      *
319      * @param name
320      * @param maxline
321      */
322     void addTest(String name, int maxline) {
323 
324         File   f    = new File(name);
325         File   fnew = new File(name + ".new");
326         String key  = name;
327 
328         key = key.replace('\\', '.');
329 
330         try {
331             LineNumberReader read = new LineNumberReader(new FileReader(f));
332             FileWriter       write    = new FileWriter(fnew);
333             int              l        = 0;
334             boolean          longline = false;
335 
336             while (true) {
337                 String line = read.readLine();
338 
339                 if (line == null) {
340                     break;
341                 }
342 
343                 if (line.startsWith(" ")) {
344                     int spaces = 0;
345 
346                     for (; spaces < line.length(); spaces++) {
347                         if (line.charAt(spaces) != ' ') {
348                             break;
349                         }
350                     }
351 
352                     if (spaces > 3 && testLine(line) &&!longline) {
353                         line = "org.hsqldb.test.Profile.visit(\"" + key
354                                + "\"," + l + "," + maxline + ");" + line;
355 
356                         l++;
357                     } else if (isLongline(line)) {
358                         longline = true;
359                     } else {
360                         longline = false;
361                     }
362                 }
363 
364                 write.write(line + ls);
365             }
366 
367             read.close();
368             write.flush();
369             write.close();
370 
371             File fbak = new File(name + ".bak");
372 
373             fbak.delete();
374             f.renameTo(fbak);
375 
376             File fcopy = new File(name);
377 
378             fnew.renameTo(fcopy);
379             fbak.delete();
380         } catch (Exception e) {
381             printError(e.getMessage());
382         }
383     }
384 
385     /**
386      * Method declaration
387      *
388      *
389      * @param name
390      *
391      * @return
392      */
393     int testFile(String name) {
394 
395         File f = new File(name);
396 
397         try {
398             LineNumberReader read = new LineNumberReader(new FileReader(f));
399             int              l        = 1,
400                              maxline  = 0;
401             boolean          longline = false;
402 
403             while (true) {
404                 String line = read.readLine();
405 
406                 if (line == null) {
407                     break;
408                 }
409 
410                 if (line.length() > MAX_LINELENGTH
411                         &&!line.startsWith("org.hsqldb.test.Profile.")) {
412                     System.out.println("long line in " + name + " at line "
413                                        + l);
414                 }
415 
416                 if (line.startsWith(" ")) {
417                     int spaces = 0;
418 
419                     for (; spaces < line.length(); spaces++) {
420                         if (line.charAt(spaces) != ' ') {
421                             break;
422                         }
423                     }
424 
425                     if (spaces > 3 && testLine(line) &&!longline) {
426                         maxline++;
427                     } else if (isLongline(line)) {
428                         longline = true;
429                     } else {
430                         longline = false;
431                     }
432 
433                     String s = line.substring(spaces);
434 
435                     if (s.startsWith("if(")) {
436                         if (!s.endsWith(" {")) {
437                             System.out.println("if( without { in " + name
438                                                + " at line " + l);
439                         }
440                     } else if (s.startsWith("} else if(")) {
441                         if (!s.endsWith(" {")) {
442                             System.out.println("} else if without { in "
443                                                + name + " at line " + l);
444                         }
445                     } else if (s.startsWith("while(")) {
446                         if (!s.endsWith(" {")) {
447                             System.out.println("while( without { in " + name
448                                                + " at line " + l);
449                         }
450                     } else if (s.startsWith("switch(")) {
451                         if (!s.endsWith(" {")) {
452                             System.out.println("switch( without { in " + name
453                                                + " at line " + l);
454                         }
455                     } else if (s.startsWith("do ")) {
456                         if (!s.endsWith(" {")) {
457                             System.out.println("do without { in " + name
458                                                + " at line " + l);
459                         }
460                     }
461                 }
462 
463                 l++;
464             }
465 
466             read.close();
467 
468             return maxline;
469         } catch (Exception e) {
470             printError(e.getMessage());
471         }
472 
473         return -1;
474     }
475 
476     /**
477      * Method declaration
478      *
479      *
480      * @param line
481      *
482      * @return
483      */
484     boolean testLine(String line) {
485 
486         if (!line.endsWith(";")) {
487             return false;
488         }
489 
490         if (line.trim().startsWith("super(")) {
491             return false;
492         }
493 
494         return true;
495     }
496 
497     /**
498      * Method declaration
499      *
500      *
501      * @param s
502      *
503      * @return
504      */
505     boolean isLongline(String s) {
506 
507         char c = s.charAt(s.length() - 1);
508 
509         if (",(+-&|".indexOf(c) >= 0) {
510             return true;
511         }
512 
513         return false;
514     }
515 
516     /**
517      * Method declaration
518      *
519      *
520      * @param name
521      *
522      * @return
523      */
524     boolean processFile(String name) {
525 
526         File    f         = new File(name);
527         File    fnew      = new File(name + ".new");
528         int     state     = 0;    // 0=normal 1=inside_if 2=inside_else
529         boolean switchoff = false;
530         boolean working   = false;
531 
532         try {
533             Vector v = getFileLines(f);
534 
535             for (int i = 0; i < v.size(); i++) {
536                 String line = (String) v.elementAt(i);
537 
538                 if (line == null) {
539                     break;
540                 }
541 
542                 if (working) {
543                     if (line.equals("/*") || line.equals("*/")) {
544                         v.removeElementAt(i--);
545 
546                         continue;
547                     }
548                 }
549 
550                 if (!line.startsWith("//#")) {
551 
552                 } else {
553                     if (line.startsWith("//#ifdef ")) {
554                         if (state != 0) {
555                             printError(
556                                 "'#ifdef' not allowed inside '#ifdef'");
557 
558                             return false;
559                         }
560 
561                         state = 1;
562 
563                         String s = line.substring(9);
564 
565                         if (vSwitchOn.indexOf(s) != -1) {
566                             working   = true;
567                             switchoff = false;
568                         } else if (vSwitchOff.indexOf(s) != -1) {
569                             working = true;
570 
571                             v.insertElementAt("/*",++i);
572 
573                             switchoff = true;
574                         }
575 
576                         if (vSwitches.indexOf(s) == -1) {
577                             vSwitches.addElement(s);
578                         }
579                     } else if (line.startsWith("//#else")) {
580                         if (state != 1) {
581                             printError("'#else' without '#ifdef'");
582 
583                             return false;
584                         }
585 
586                         state = 2;
587 
588                         if (!working) {
589 
590                         } else if (switchoff) {
591                             if (v.elementAt(i - 1).equals("")) {
592                                 v.insertElementAt("*/",i - 1);
593 
594                                 i++;
595                             } else {
596                                 v.insertElementAt( "*/",i++);
597                             }
598 
599                             switchoff = false;
600                         } else {
601 
602                             v.insertElementAt("/*",++i);
603 
604                             switchoff = true;
605                         }
606                     } else if (line.startsWith("//#endif")) {
607                         if (state == 0) {
608                             printError("'#endif' without '#ifdef'");
609 
610                             return false;
611                         }
612 
613                         state = 0;
614 
615                         if (working && switchoff) {
616                             if (v.elementAt(i - 1).equals("")) {
617                                 v.insertElementAt( "*/", i - 1);
618 
619                                 i++;
620                             } else {
621                                 v.insertElementAt("*/",i++ );
622                             }
623                         }
624 
625                         working = false;
626                     } else {
627 
628                     }
629                 }
630             }
631 
632             if (state != 0) {
633                 printError("'#endif' missing");
634 
635                 return false;
636             }
637 
638             writeFileLines(v, fnew);
639 
640             File fbak = new File(name + ".bak");
641 
642             fbak.delete();
643             f.renameTo(fbak);
644 
645             File fcopy = new File(name);
646 
647             fnew.renameTo(fcopy);
648             fbak.delete();
649 
650             return true;
651         } catch (Exception e) {
652             printError(e.getMessage());
653 
654             return false;
655         }
656     }
657 
658     static Vector getFileLines(File f) throws IOException {
659 
660         LineNumberReader read = new LineNumberReader(new FileReader(f));
661         Vector           v    = new Vector();
662 
663         for (;;) {
664             String line = read.readLine();
665 
666             if (line == null) {
667                 break;
668             }
669 
670             v.addElement(line);
671         }
672 
673         read.close();
674 
675         return v;
676     }
677 
678     static void writeFileLines(Vector v, File f) throws IOException {
679 
680         FileWriter write = new FileWriter(f);
681 
682         for (int i = 0; i < v.size(); i++) {
683             write.write((String) v.elementAt(i));
684             write.write(ls);
685         }
686 
687         write.flush();
688         write.close();
689     }
690 
691     /**
692      * Method declaration
693      *
694      *
695      * @param error
696      */
697     static void printError(String error) {
698         System.out.println("");
699         System.out.println("ERROR: " + error);
700     }
701 }