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