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