1
2
3
4
5
6 package org.andromda.utils;
7
8 import java.io.File;
9 import java.io.FileInputStream;
10 import java.io.FileOutputStream;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19 import java.util.zip.ZipEntry;
20 import java.util.zip.ZipInputStream;
21 import java.util.zip.ZipOutputStream;
22 import org.apache.commons.io.FileUtils;
23 import org.apache.commons.io.filefilter.FileFilterUtils;
24 import org.apache.commons.io.filefilter.IOFileFilter;
25 import org.apache.commons.lang.StringUtils;
26
27
28
29
30
31
32
33 public class GlobalPatternFileReplace
34 {
35 private static List<Replacement> replacements = new ArrayList<Replacement>();
36 private static int MAX_FILE_SIZE = 10000000;
37 private static Set<String> extensions = new HashSet<String>();
38 private static int filesScanned = 0;
39 private static int filesModified = 0;
40 private static int fileReplacements = 0;
41
42
43
44
45 public GlobalPatternFileReplace()
46 {
47
48 }
49
50
51
52
53
54 public static void main(String[] args) throws IOException
55 {
56 File file = new File("C:/workspaces/A34/andromda341/cartridges/andromda-spring/pom.xml");
57
58 String dir = null;
59 for (int i = 0; i < args.length; i++)
60 {
61 if (args[i].startsWith("-"))
62 {
63 if (args[i].equals("-ext"))
64 {
65 if (i + 1 >= args.length)
66 {
67 printUsageAndExit();
68 }
69 parseCommaSeparatedList(args[++i], extensions);
70 }
71 else
72 {
73 System.err.println("Unknown switch " + args[i]);
74 printUsageAndExit();
75 }
76 }
77 else
78 {
79 if (dir != null)
80 {
81 printUsageAndExit();
82 }
83 else
84 {
85 dir = args[i];
86 file = new File(dir);
87 }
88 }
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102 if (extensions.isEmpty())
103 {
104 parseCommaSeparatedList("xml,java,xml.zip,vsl,vm", extensions);
105 }
106
107 try
108 {
109
110
111
112 readMapping("packageMapping.txt", replacements, true);
113
114
115
116
117 System.out.println("Migrating your files in " + file.getCanonicalPath());
118 replaceInAllFiles(file);
119 }
120 catch (IOException e)
121 {
122
123 e.printStackTrace();
124 }
125
126 System.out.println("Migration complete.");
127 System.out.println("Scanned " + filesScanned + " files. " + filesModified + " files modified.");
128 }
129
130
131
132
133 private static void printUsageAndExit()
134 {
135 System.err.println("Usage: java " + GlobalPatternFileReplace.class.getName() + " <directory> [-ext <fileExtensions>]");
136 System.err.println("<fileExtensions> is a comma separated list of file extensions to process, e.g.: java,xml,properties");
137 System.err.println("\tUse a trailing comma to include files with no extension (meaning their name contains no dot)");
138 System.exit(1);
139 }
140
141
142
143
144
145
146
147
148 private static void replaceInAllFiles(File dir) throws IOException
149 {
150 if (dir.isDirectory())
151 {
152 IOFileFilter fileFilter = FileFilterUtils.trueFileFilter();
153 IOFileFilter notTargetFileFilter = FileFilterUtils.notFileFilter(FileFilterUtils.nameFileFilter("target"));
154 IOFileFilter dirFilter = FileFilterUtils.and(FileFilterUtils.makeSVNAware(null), notTargetFileFilter);
155 Collection<File> files = FileUtils.listFiles(dir, fileFilter, dirFilter);
156 for (File file : files)
157 {
158 if (file.isFile())
159 {
160 boolean process = false;
161
162 for (String ext : extensions)
163 {
164 if (file.getName().endsWith("." + ext))
165 {
166 process = true;
167 break;
168 }
169 }
170 if (process)
171 {
172
173
174 if (file.getName().endsWith(".zip"))
175 {
176 replaceInArchive(file);
177 }
178 else
179 {
180 replaceInFile(file);
181 }
182 }
183 }
184
185
186 else if (file.isDirectory())
187 {
188 replaceInAllFiles(file);
189 }
190 }
191 }
192 if (dir.isFile())
193 {
194 if (dir.getName().endsWith(".zip"))
195 {
196 replaceInArchive(dir);
197 }
198 else
199 {
200 replaceInFile(dir);
201 }
202 }
203 }
204
205
206
207
208
209
210 private static boolean checkAttributes(File file) throws IOException
211 {
212
213 if (!extensions.isEmpty())
214 {
215 String filename = file.getName();
216 String ext = "";
217 int lastDot = filename.lastIndexOf('.');
218 if (lastDot > -1)
219 {
220 ext = filename.substring(lastDot + 1);
221 }
222 if (!extensions.contains(ext.toLowerCase()))
223 {
224 return false;
225 }
226 }
227
228
229 if (!file.canRead())
230 {
231
232
233 System.err.println("Can't read file: " + file.getCanonicalPath());
234
235 }
236
237
238
239
240
241
242 if (file.length() > MAX_FILE_SIZE)
243 {
244 System.out.println("Skipping file " + file.getCanonicalPath() + " with size: " + file.length() + " bytes");
245 return false;
246 }
247
248 return true;
249 }
250
251
252
253
254
255
256 private static int replaceInArchive(File file) throws IOException
257 {
258
259
260 int replacements = 0;
261
262 if (file.isFile() && file.getName().endsWith(".zip"))
263 {
264 File location = unpack(file);
265 IOFileFilter fileFilter = FileFilterUtils.suffixFileFilter("xml");
266 IOFileFilter dirFilter = FileFilterUtils.makeCVSAware(null);
267 Collection<File> archiveFiles = FileUtils.listFiles(location, fileFilter, dirFilter);
268 for (File archiveFile : archiveFiles)
269 {
270
271 int replacement = replaceInFile(archiveFile);
272 if (replacement > 0)
273 {
274 pack(file, archiveFile.getAbsolutePath());
275 replacements += replacement;
276 }
277 archiveFile.delete();
278 }
279 location.delete();
280 }
281 return replacements;
282 }
283
284
285
286
287
288
289 private static int replaceInFile(File file) throws IOException
290 {
291
292 fileReplacements = 0;
293 if (!checkAttributes(file))
294 {
295 return fileReplacements;
296 }
297 String original;
298 try
299 {
300 original = FileUtils.readFileToString(file);
301 }
302 catch (IOException e)
303 {
304 System.err.println("Error reading " + file.getCanonicalPath());
305 System.err.println(e.getMessage());
306 return fileReplacements;
307 }
308 String contents = original;
309 contents = replaceInPattern(contents);
310
311
312 if (!contents.equals(original))
313 {
314 if (!file.canWrite())
315 {
316
317 file.setReadable(true, false);
318 System.out.println("Making file writable: " + file.getCanonicalPath());
319
320 }
321 if (!file.canWrite())
322 {
323 System.err.println("Could not make file writable: " + file.getCanonicalPath());
324 }
325 else
326 {
327 FileUtils.writeStringToFile(file, contents);
328 filesModified++;
329 }
330 System.out.println(file.getAbsolutePath() + " " + fileReplacements + " replacements");
331 }
332 filesScanned++;
333
334
335
336
337 return fileReplacements;
338 }
339
340
341
342
343
344
345
346
347 protected static File unpack(
348 final File file)
349 throws IOException
350 {
351 return unpack(file, null);
352 }
353
354
355
356
357
358
359
360
361
362 protected static File unpack(
363 final File file,
364 File location)
365 throws IOException
366 {
367 final int ext = file.getAbsolutePath().lastIndexOf('.');
368 if (ext<1)
369 {
370 throw new IOException("File has no extension: " + file.getAbsolutePath());
371 }
372
373 if (location==null || !location.exists())
374 {
375 location = new File(file.getParent() + "/" + StringUtils.remove(file.getName(), '.') + "/");
376 }
377 if (!location.getAbsolutePath().endsWith("/") && !location.getAbsolutePath().endsWith("\\"))
378 {
379 location = new File(location.getAbsolutePath() + "/");
380 }
381 if (!location.exists())
382 {
383
384 FileUtils.forceMkdir(location);
385 }
386
387
388 try
389 {
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404 byte[] buf = new byte[1024];
405 ZipInputStream zipinputstream = null;
406 ZipEntry zipentry;
407 zipinputstream = new ZipInputStream(new FileInputStream(file));
408
409 zipentry = zipinputstream.getNextEntry();
410 while (zipentry != null)
411 {
412
413 String entryName = zipentry.getName();
414
415 FileOutputStream fileoutputstream;
416 File newFile = new File(entryName);
417 String directory = newFile.getParent();
418
419 if(directory == null)
420 {
421 if(newFile.isDirectory())
422 break;
423 }
424
425 File output = new File(location.getAbsolutePath(), entryName);
426 fileoutputstream = new FileOutputStream(output);
427
428 int n;
429 while ((n = zipinputstream.read(buf, 0, 1024)) > -1)
430 fileoutputstream.write(buf, 0, n);
431
432 fileoutputstream.close();
433 zipinputstream.closeEntry();
434 zipentry = zipinputstream.getNextEntry();
435
436 }
437
438 zipinputstream.close();
439 }
440 catch (Exception e)
441 {
442 e.printStackTrace();
443 }
444 return location;
445 }
446
447
448
449
450
451
452
453
454
455 private static void pack(
456 final File zipArchive,
457 final String path)
458 throws IOException
459 {
460
461
462
463
464
465 final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipArchive));
466 File pathFile = new File(path);
467 final ZipEntry zipEntry = new ZipEntry(pathFile.getName());
468 zipEntry.setMethod(ZipEntry.DEFLATED);
469 zipOutputStream.putNextEntry(zipEntry);
470 final FileInputStream inputStream = new FileInputStream(path);
471 final byte[] buffer = new byte[1024];
472 int n = 0;
473 while ((n =
474 inputStream.read(
475 buffer,
476 0,
477 buffer.length)) > 0)
478 {
479 zipOutputStream.write(
480 buffer,
481 0,
482 n);
483 }
484 inputStream.close();
485 zipOutputStream.closeEntry();
486 zipOutputStream.close();
487 }
488
489
490
491
492
493
494
495 private static String replaceInPattern(String contents)
496 {
497
498 for (Replacement replacement : replacements)
499 {
500
501 contents = replaceInPattern(contents, replacement);
502 }
503 return contents;
504 }
505
506
507
508
509
510
511
512 private static String replaceInPattern(String contents, Replacement replacement)
513 {
514
515 Matcher matcher = replacement.pattern.matcher(contents);
516 StringBuffer sb = new StringBuffer();
517 while (matcher.find())
518 {
519 boolean ignoreString = false;
520 String toReplace = contents.substring(matcher.start(), matcher.end());
521 for (String ignorePattern : replacement.ignorePatterns)
522 {
523 if (toReplace.indexOf(ignorePattern) > -1)
524 {
525 ignoreString = true;
526 break;
527 }
528 }
529 if (!ignoreString)
530 {
531 toReplace = toReplace.replace(replacement.replaceStr, replacement.replaceWithStr);
532 toReplace = StringUtils.remove(toReplace, replacement.deleteStr);
533 matcher.appendReplacement(sb, toReplace);
534 fileReplacements++;
535 }
536 }
537 sb = matcher.appendTail(sb);
538 return sb.toString();
539 }
540
541
542
543
544
545
546
547
548 private static Set<String> parseCommaSeparatedList(String string, Set<String> results)
549 {
550 String[] components = string.split(",", -1);
551 if (results==null)
552 {
553 results = new HashSet<String>();
554 }
555 for (int i = 0; i < components.length; i++)
556 {
557 results.add(components[i]);
558 }
559 return results;
560 }
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575 private static void readMapping(String fileName, List mappings, boolean treatAsPackageNames) throws IOException
576 {
577
578
579
580
581 Replacement replacement = new Replacement("@andromda.([a-z]+[\\\\.])+[a-z]", ".", "_", "@", parseCommaSeparatedList(".cvs.", null));
582 GlobalPatternFileReplace.replacements.add(replacement);
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624 }
625
626
627
628
629
630
631
632 private static class Replacement
633 {
634 String regex;
635 String deleteStr;
636 String replaceStr;
637 String replaceWithStr;
638 Set<String> ignorePatterns;
639 Pattern pattern;
640
641
642
643
644
645
646
647
648 Replacement(String regexIn, String replacement, String replaceWithIn, String deleteStrIn, Set<String> ignorePatternsIn)
649 {
650 this.regex = regexIn;
651 this.replaceStr = replacement;
652 this.deleteStr = deleteStrIn;
653 this.replaceWithStr = replaceWithIn;
654 this.ignorePatterns = ignorePatternsIn;
655 this.pattern = Pattern.compile(regex);
656 }
657 }
658 }