1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.config;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.nio.file.FileVisitResult;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.nio.file.SimpleFileVisitor;
26 import java.nio.file.attribute.BasicFileAttributes;
27 import java.util.concurrent.atomic.AtomicInteger;
28
29 import org.apache.logging.log4j.core.config.ConfigurationException;
30 import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
31 import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
32 import org.apache.logging.log4j.core.tools.BasicCommandLineArguments;
33 import org.apache.logging.log4j.core.tools.picocli.CommandLine;
34 import org.apache.logging.log4j.core.tools.picocli.CommandLine.Command;
35 import org.apache.logging.log4j.core.tools.picocli.CommandLine.Option;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public final class Log4j1ConfigurationConverter {
54
55 @Command(name = "Log4j1ConfigurationConverter")
56 public static class CommandLineArguments extends BasicCommandLineArguments implements Runnable {
57
58 @Option(names = { "--failfast", "-f" }, description = "Fails on the first failure in recurse mode.")
59 private boolean failFast;
60
61 @Option(names = { "--in", "-i" }, description = "Specifies the input file.")
62 private Path pathIn;
63
64 @Option(names = { "--out", "-o" }, description = "Specifies the output file.")
65 private Path pathOut;
66
67 @Option(names = { "--recurse", "-r" }, description = "Recurses into this folder looking for the input file")
68 private Path recurseIntoPath;
69
70 @Option(names = { "--verbose", "-v" }, description = "Be verbose.")
71 private boolean verbose;
72
73 public Path getPathIn() {
74 return pathIn;
75 }
76
77 public Path getPathOut() {
78 return pathOut;
79 }
80
81 public Path getRecurseIntoPath() {
82 return recurseIntoPath;
83 }
84
85 public boolean isFailFast() {
86 return failFast;
87 }
88
89 public boolean isVerbose() {
90 return verbose;
91 }
92
93 public void setFailFast(final boolean failFast) {
94 this.failFast = failFast;
95 }
96
97 public void setPathIn(final Path pathIn) {
98 this.pathIn = pathIn;
99 }
100
101 public void setPathOut(final Path pathOut) {
102 this.pathOut = pathOut;
103 }
104
105 public void setRecurseIntoPath(final Path recurseIntoPath) {
106 this.recurseIntoPath = recurseIntoPath;
107 }
108
109 public void setVerbose(final boolean verbose) {
110 this.verbose = verbose;
111 }
112
113 @Override
114 public void run() {
115 if (isHelp()) {
116 CommandLine.usage(this, System.err);
117 return;
118 }
119 new Log4j1ConfigurationConverter(this).run();
120 }
121
122 @Override
123 public String toString() {
124 return "CommandLineArguments [recurseIntoPath=" + recurseIntoPath + ", verbose=" + verbose + ", pathIn="
125 + pathIn + ", pathOut=" + pathOut + "]";
126 }
127 }
128
129 private static final String FILE_EXT_XML = ".xml";
130
131 public static void main(final String[] args) {
132 CommandLine.run(new CommandLineArguments(), System.err, args);
133 }
134
135 public static Log4j1ConfigurationConverter run(final CommandLineArguments cla) {
136 final Log4j1ConfigurationConverter log4j1ConfigurationConverter = new Log4j1ConfigurationConverter(cla);
137 log4j1ConfigurationConverter.run();
138 return log4j1ConfigurationConverter;
139 }
140
141 private final CommandLineArguments cla;
142
143 private Log4j1ConfigurationConverter(final CommandLineArguments cla) {
144 this.cla = cla;
145 }
146
147 protected void convert(final InputStream input, final OutputStream output) throws IOException {
148 final ConfigurationBuilder<BuiltConfiguration> builder = new Log4j1ConfigurationParser()
149 .buildConfigurationBuilder(input);
150 builder.writeXmlConfiguration(output);
151 }
152
153 InputStream getInputStream() throws IOException {
154 final Path pathIn = cla.getPathIn();
155 return pathIn == null ? System.in : new InputStreamWrapper(Files.newInputStream(pathIn), pathIn.toString());
156 }
157
158 OutputStream getOutputStream() throws IOException {
159 final Path pathOut = cla.getPathOut();
160 return pathOut == null ? System.out : Files.newOutputStream(pathOut);
161 }
162
163 private void run() {
164 if (cla.getRecurseIntoPath() != null) {
165 final AtomicInteger countOKs = new AtomicInteger();
166 final AtomicInteger countFails = new AtomicInteger();
167 try {
168 Files.walkFileTree(cla.getRecurseIntoPath(), new SimpleFileVisitor<Path>() {
169 @Override
170 public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs)
171 throws IOException {
172 if (cla.getPathIn() == null || file.getFileName().equals(cla.getPathIn())) {
173 verbose("Reading %s", file);
174 String newFile = file.getFileName().toString();
175 final int lastIndex = newFile.lastIndexOf(".");
176 newFile = lastIndex < 0 ? newFile + FILE_EXT_XML
177 : newFile.substring(0, lastIndex) + FILE_EXT_XML;
178 final Path resolved = file.resolveSibling(newFile);
179 try (final InputStream input = new InputStreamWrapper(Files.newInputStream(file), file.toString());
180 final OutputStream output = Files.newOutputStream(resolved)) {
181 try {
182 convert(input, output);
183 countOKs.incrementAndGet();
184 } catch (ConfigurationException | IOException e) {
185 countFails.incrementAndGet();
186 if (cla.isFailFast()) {
187 throw e;
188 }
189 e.printStackTrace();
190 }
191 verbose("Wrote %s", resolved);
192 }
193 }
194 return FileVisitResult.CONTINUE;
195 }
196 });
197 } catch (final IOException e) {
198 throw new ConfigurationException(e);
199 } finally {
200 verbose("OK = %,d, Failures = %,d, Total = %,d", countOKs.get(), countFails.get(),
201 countOKs.get() + countFails.get());
202 }
203 } else {
204 verbose("Reading %s", cla.getPathIn());
205 try (final InputStream input = getInputStream(); final OutputStream output = getOutputStream()) {
206 convert(input, output);
207 } catch (final IOException e) {
208 throw new ConfigurationException(e);
209 }
210 verbose("Wrote %s", cla.getPathOut());
211 }
212 }
213
214 private void verbose(final String template, final Object... args) {
215 if (cla.isVerbose()) {
216 System.err.println(String.format(template, args));
217 }
218 }
219
220 }