Changed license to CC0.
[meviz.git] / src / main / java / eu / svjatoslav / meviz / bomremove / Main.java
1 /*
2  * Meviz - Various tools collection to work with multimedia. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5
6
7 package eu.svjatoslav.meviz.bomremove;
8
9 import eu.svjatoslav.commons.file.IOHelper;
10 import eu.svjatoslav.commons.string.GlobMatcher;
11 import eu.svjatoslav.meviz.Module;
12
13 import java.io.File;
14 import java.io.FileInputStream;
15 import java.io.IOException;
16 import java.util.Arrays;
17
18 public class Main implements Module {
19
20     private final byte[] bomHeader = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf};
21
22     private final CommandlineHandler commandlineHandler = new CommandlineHandler();
23
24     private BomStrippingOptions options;
25
26     private boolean contains(final byte[] header, final byte[] patternToSeek) {
27
28         for (int i = 0; i < patternToSeek.length; i++)
29             if (header[i] != patternToSeek[i])
30                 return false;
31
32         return true;
33     }
34
35     private boolean fileContainsHeader(final File file)
36             throws IOException {
37
38         final FileInputStream fileInputStream = new FileInputStream(file);
39
40         final byte[] currentFileHeader = new byte[bomHeader.length];
41         fileInputStream.read(currentFileHeader);
42         fileInputStream.close();
43
44         return contains(currentFileHeader, bomHeader);
45     }
46
47     private boolean fileMatchesInputPattern(final File file) {
48         final String fileName = file.getName().toLowerCase();
49
50         for (final String inputPattern : options.inputPatterns)
51             if (GlobMatcher.match(fileName, inputPattern.toLowerCase()))
52                 return true;
53
54         return false;
55     }
56
57     @Override
58     public String getDescription() {
59         return "Remove byte order mark (bom) from UTF text files if they are present.";
60     }
61
62     @Override
63     public String getModuleCommand() {
64         return "stripbom";
65     }
66
67     private void processDirectory(final File directory) {
68
69         for (final File subFile : directory.listFiles())
70             if (subFile.isDirectory()) {
71                 if (options.recursive)
72                     processDirectory(subFile);
73             } else if (fileMatchesInputPattern(subFile))
74                 try {
75                     processFile(subFile);
76                 } catch (final IOException exception) {
77                     System.out.println("Error processing file: "
78                             + subFile.getAbsolutePath());
79                     System.out.println("   exception: "
80                             + exception.getMessage());
81                 }
82
83     }
84
85     private void processFile(final File file) throws IOException {
86
87         if (file.length() < bomHeader.length)
88             return;
89
90         if (!fileContainsHeader(file))
91             return;
92
93         System.out.println("Removing BOM from: " + file.getAbsolutePath());
94         stripFileFromHeader(file);
95     }
96
97     @Override
98     public void run(final String[] args) throws IOException {
99
100         options = commandlineHandler.parseCommandlineArguments(args);
101
102         if (options == null) {
103             showCommandlineHelp();
104             return;
105         }
106
107         processDirectory(options.targetDirectory);
108
109     }
110
111     @Override
112     public void showCommandlineHelp() {
113         commandlineHandler.parser.showHelp();
114     }
115
116     private void stripFileFromHeader(final File file)
117             throws IOException {
118         // read entire file
119         final byte[] fileContents = IOHelper.getFileContents(file);
120
121         // remove BOM header form file
122         final byte[] newFileContents = Arrays.copyOfRange(fileContents,
123                 bomHeader.length, fileContents.length);
124
125         // overwrite file with new contents
126         IOHelper.saveToFile(file, newFileContents);
127     }
128
129 }