KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > tools > code > CodeSwitch


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.tools.code;
6
7
8 import java.io.*;
9 import java.util.*;
10
11 /**
12  * @author Thomas
13  * TODO codeswitch: replace with ant 'Replace' task is possible
14  */

15 public class CodeSwitch {
16     private boolean recurse;
17     private ArrayList list = new ArrayList();
18     private ArrayList switchOn = new ArrayList();
19     private ArrayList switchOff = new ArrayList();
20     private ArrayList switches = new ArrayList();
21     private byte[] file;
22     private String JavaDoc endOfLine;
23     private ArrayList lines;
24     private boolean changed;
25
26     public static void main(String JavaDoc[] argv) {
27         (new CodeSwitch()).run(argv);
28     }
29
30     private void run(String JavaDoc[] a) {
31         if (a.length == 0) {
32             showUsage();
33             return;
34         }
35         boolean path = false;
36         recurse = true;
37         for (int i = 0; i < a.length; i++) {
38             String JavaDoc p = a[i];
39             if (p.startsWith("+")) {
40                 switchOn.add(p.substring(1));
41             } else if (p.startsWith("-r+")) {
42                 // (default)
43
recurse = true;
44             } else if (p.startsWith("-r-")) {
45                 recurse = false;
46             } else if (p.startsWith("-")) {
47                 switchOff.add(p.substring(1));
48             } else {
49                 addDir(p, true);
50                 path = true;
51             }
52         }
53         if (!path) {
54             printError("no path specified");
55             showUsage();
56         }
57         process();
58         if (switchOff.size() == 0 && switchOn.size() == 0) {
59             printSwitches();
60         }
61     }
62
63     private void showUsage() {
64         String JavaDoc className = getClass().getName();
65         System.out.println("Usage: java " + className
66                 + " [-r+] [-r-] paths [+|-][labels]");
67         System.out.println("If no labels are specified then all used");
68         System.out.println("labels in the source code are shown.");
69         System.out.println("-r+ recurse subdirectories (default)");
70         System.out.println("-r- do not recurse subdirectories");
71         System.out.println("Use +MODE to switch on the things labeld MODE");
72         System.out.println("Use -MODE to switch off the things labeld MODE");
73         System.out
74                 .println("Path: Any number of path or files may be specified.");
75         System.out
76                 .println(" Use . for the current directory (including sub-directories).");
77         System.out.println("Example: java " + className + " +JAVA2 .");
78         System.out
79                 .println("This example switches on code labeled JAVA2 in all *.java files");
80         System.out.println("in the current directory and all subdirectories.");
81     }
82
83     private void process() {
84         int len = list.size();
85         for (int i = 0; i < len; i++) {
86             String JavaDoc fileName = (String JavaDoc) list.get(i);
87             if (!processFile(fileName)) {
88                 System.out.println("in file " + fileName
89                         + " - this file is skipped");
90             }
91         }
92     }
93
94     private void printSwitches() {
95         System.out.println("Used labels:");
96         for (int i = 0; i < switches.size(); i++) {
97             System.out.println((String JavaDoc) (switches.get(i)));
98         }
99     }
100
101     private void addDir(String JavaDoc path, boolean recurseMore) {
102         File f = new File(path);
103         if (f.isFile() && path.endsWith(".java")) {
104             list.add(path);
105         } else if (f.isDirectory()) {
106             if (recurse || recurseMore) {
107                 // one recursion at least
108
String JavaDoc[] files = f.list();
109                 for (int i = 0; i < files.length; i++) {
110                     addDir(path + File.separatorChar + files[i], false);
111                 }
112             }
113         }
114     }
115
116     // lines are terminated with \r, \n or \r\n
117
private void breakIntoLines() {
118         lines = new ArrayList();
119         int len = file.length;
120         int last = 0;
121         int cr = 0, lf = 0, crlf = 0;
122         for (int i = 0; i < len; i++) {
123             byte c = file[i];
124             if (c == '\r' || c == '\n') {
125                 if (c == '\r') {
126                     if (i < len - 1 && file[i + 1] == '\n') {
127                         i++;
128                         crlf++;
129                     } else {
130                         cr++;
131                     }
132                 } else {
133                     lf++;
134                 }
135                 if (i < len) {
136                     lines.add(new String JavaDoc(file, last, i - last + 1));
137                     last = i + 1;
138                 }
139             }
140         }
141         if (cr > lf && cr > crlf) {
142             endOfLine = "\r";
143         } else if (lf > crlf) {
144             endOfLine = "\n";
145         } else {
146             endOfLine = "\r\n";
147         }
148         lines.add(new String JavaDoc(file, last, len - last));
149     }
150
151     private String JavaDoc getLine(int line) {
152         return (String JavaDoc) lines.get(line);
153     }
154
155     private void insertLine(int line, String JavaDoc s) {
156         lines.add(line, s);
157         changed = true;
158     }
159
160     private void removeLine(int line) {
161         lines.remove(line);
162         changed = true;
163     }
164
165     private boolean processFile(String JavaDoc name) {
166         File f = new File(name);
167         boolean switchoff = false;
168         boolean working = false;
169         int state = 0;
170         try {
171             long rawLen = f.length();
172             if (rawLen > Integer.MAX_VALUE) {
173                 printError("Files bigger than Integer.MAX_VALUE are not supported");
174                 return false;
175             }
176             int len = (int) rawLen;
177             file = new byte[len];
178             RandomAccessFile read = new RandomAccessFile(f, "r");
179             read.readFully(file);
180             read.close();
181             breakIntoLines();
182             changed = false;
183
184             for (int i = 0; i < lines.size(); i++) {
185                 String JavaDoc line = getLine(i);
186                 String JavaDoc lineTrim = line.trim();
187                 if (working) {
188                     if (lineTrim.startsWith("/*") || lineTrim.startsWith("*/")) {
189                         removeLine(i);
190                         i--;
191                         continue;
192                     }
193                 }
194                 if (lineTrim.startsWith("//#")) {
195                     if (lineTrim.startsWith("//#ifdef ")) {
196                         if (state != 0) {
197                             printError("//#ifdef not allowed inside //#ifdef");
198                             return false;
199                         }
200                         state = 1;
201                         String JavaDoc s = lineTrim.substring(9);
202                         boolean switchedOn = false;
203                         boolean switchedOff = false;
204                         if (switchOn.indexOf(s) != -1) {
205                             switchedOn = true;
206                         }
207                         if (switchOff.indexOf(s) != -1) {
208                             switchedOff = true;
209                         }
210                         if (s.indexOf("&&") != -1) {
211                             switchedOn = true;
212                             s += "&&";
213                             while (s.length() > 0) {
214                                 int id = s.indexOf("&&");
215                                 if (id == -1) {
216                                     break;
217                                 }
218                                 String JavaDoc s1 = s.substring(0, id).trim();
219                                 s = s.substring(id + 2).trim();
220                                 if (switches.indexOf(s1) == -1) {
221                                     switches.add(s1);
222                                     switchedOn = false;
223                                 }
224                                 if (switchOn.indexOf(s1) == -1) {
225                                     switchedOff = true;
226                                     switchedOn = false;
227                                 }
228                                 if (switchOff.indexOf(s1) != -1) {
229                                     switchedOff = true;
230                                     switchedOn = false;
231                                 }
232                             }
233                         }
234                         if (switchedOn) {
235                             working = true;
236                             switchoff = false;
237                         } else if (switchedOff) {
238                             working = true;
239                             insertLine(++i, "/*" + endOfLine);
240                             switchoff = true;
241                         }
242                         if (switches.indexOf(s) == -1) {
243                             switches.add(s);
244                         }
245                     } else if (lineTrim.startsWith("//#else")) {
246                         if (state != 1) {
247                             printError("//#else without //#ifdef");
248                             return false;
249                         }
250                         state = 2;
251                         if (working) {
252                             if (switchoff) {
253                                 insertLine(++i, "*/" + endOfLine);
254                                 switchoff = false;
255                             } else {
256                                 insertLine(++i, "/*" + endOfLine);
257                                 switchoff = true;
258                             }
259                         }
260                     } else if (lineTrim.startsWith("//#endif")) {
261                         if (state == 0) {
262                             printError("//#endif without //#ifdef");
263                             return false;
264                         }
265                         state = 0;
266                         if (working && switchoff) {
267                             insertLine(i++, "*/" + endOfLine);
268                         }
269                         working = false;
270                     }
271                 }
272             }
273             if (state != 0) {
274                 printError("//#endif missing");
275                 return false;
276             }
277             if (changed) {
278                 File fnew = new File(name + ".new");
279                 FileWriter write = new FileWriter(fnew);
280                 for (int i = 0; i < lines.size(); i++) {
281                     write.write(getLine(i));
282                 }
283                 write.close();
284                 File fbak = new File(name + ".bak");
285                 fbak.delete();
286                 f.renameTo(fbak);
287                 File fcopy = new File(name);
288                 fnew.renameTo(fcopy);
289                 fbak.delete();
290                 System.out.println(name);
291             }
292             return true;
293         } catch (Exception JavaDoc e) {
294             printError(e);
295             return false;
296         }
297     }
298
299     private static void printError(Exception JavaDoc e) {
300         e.printStackTrace();
301     }
302
303     private static void printError(String JavaDoc s) {
304         System.out.println("ERROR: " + s);
305     }
306 }
307
308
Popular Tags