Skip to content

Commit e41af11

Browse files
committed
wip3
1 parent a90e527 commit e41af11

3 files changed

Lines changed: 151 additions & 32 deletions

File tree

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,9 @@
371371
<version>3.9.9</version>
372372
</dependency>
373373
<dependency>
374-
<groupId>org.eclipse.sisu</groupId>
375-
<artifactId>org.eclipse.sisu.plexus</artifactId>
376-
<version>0.3.5</version>
374+
<groupId>org.fusesource.jansi</groupId>
375+
<artifactId>jansi</artifactId>
376+
<version>2.4.1</version>
377377
</dependency>
378378
</dependencies>
379379

src/test/java/pl/project13/log/MavenLogger.java

Lines changed: 144 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,185 @@
11
package pl.project13.log;
22

3-
import org.apache.maven.monitor.logging.DefaultLog;
4-
import org.apache.maven.plugin.AbstractMojo;
5-
import org.apache.maven.plugin.logging.Log;
3+
import org.apache.maven.shared.utils.logging.MessageUtils;
64
import org.slf4j.ILoggerFactory;
75
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
87
import org.slf4j.event.Level;
8+
import org.slf4j.helpers.FormattingTuple;
99
import org.slf4j.helpers.MessageFormatter;
1010

11-
import org.slf4j.impl.MavenSimpleLogger;
12-
import org.slf4j.impl.MavenSimpleLoggerFactory;
13-
import org.slf4j.impl.SimpleLoggerFactory;
14-
1511
import java.lang.reflect.InvocationHandler;
1612
import java.lang.reflect.InvocationTargetException;
1713
import java.lang.reflect.Method;
1814
import java.lang.reflect.Proxy;
15+
import java.util.Arrays;
1916

2017
/**
2118
* Attempts to route logging to Maven Plugin / Mojo output during Maven builds.
2219
* Falls back to System.out if routing fails.
2320
*/
24-
public class MavenLogger implements ILoggerFactory, InvocationHandler {
21+
public class MavenLogger implements InvocationHandler, ILoggerFactory {
22+
private static final MavenLogger INSTANCE = new MavenLogger();
2523
private static final CombinedLogger PROXY = (CombinedLogger) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] { CombinedLogger.class }, INSTANCE);
24+
private static final Level OUTPUT_LEVEL;
25+
26+
static {
27+
MessageUtils.setColorEnabled(true);
28+
29+
ILoggerFactory context = LoggerFactory.getILoggerFactory();
30+
Logger logger = context.getLogger(MavenLogger.class.getName());
31+
int level = 0;
32+
if(logger.isErrorEnabled())
33+
level++;
34+
if(logger.isWarnEnabled())
35+
level++;
36+
if(logger.isInfoEnabled())
37+
level++;
38+
if(logger.isDebugEnabled())
39+
level++;
40+
if(logger.isTraceEnabled())
41+
level++;
42+
OUTPUT_LEVEL = Level.values()[level];
43+
44+
log(Level.INFO, "Output level: {}", OUTPUT_LEVEL);
45+
if(logger.isDebugEnabled())
46+
log(Level.DEBUG, "Debugging enabled");
47+
}
48+
49+
private MavenLogger() {
50+
// Prevent instantiation
51+
}
52+
53+
public static void log(Object... args) {
54+
log(null, args);
55+
}
2656

27-
private static final Level OUTPUT_LEVEL = Level.INFO;
57+
public static void log(Level level, Object... args) {
58+
if(level == null)
59+
level = Level.INFO;
60+
if(level.ordinal() > OUTPUT_LEVEL.ordinal()) {
61+
return;
62+
}
63+
final String prepend;
64+
switch(level) {
65+
case TRACE:
66+
case DEBUG: {
67+
prepend = MessageUtils.level().debug(level.name());
68+
break;
69+
}
70+
case WARN: {
71+
prepend = MessageUtils.level().warning(level.name());
72+
break;
73+
}
74+
case ERROR: {
75+
prepend = MessageUtils.level().error(level.name());
76+
break;
77+
}
78+
case INFO:
79+
default: {
80+
prepend = MessageUtils.level().info(level.name());
81+
break;
82+
}
83+
}
84+
System.out.println("[" + prepend + "] " + format(args));
85+
}
2886

29-
public static CombinedLogger getLogger() {
87+
public static CombinedLogger combinedLogger() {
3088
return PROXY;
3189
}
3290

33-
@Override
34-
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
35-
if(method.getName().equals("getName")) {
36-
return MavenLogger.class.getName();
91+
public static String getName() {
92+
return MavenLogger.class.getName();
93+
}
94+
95+
private static Method matchMethod(Method requested) {
96+
for(Method implemented : INSTANCE.getClass().getDeclaredMethods()) {
97+
if(methodsMatch(requested, implemented)) {
98+
return implemented;
99+
}
37100
}
101+
return null;
102+
}
103+
104+
public static boolean methodsMatch(Method requested, Method actual) {
105+
if(requested.getName().equals(actual.getName())) {
106+
if(!requested.getReturnType().equals(actual.getReturnType()))
107+
return false;
108+
return Arrays.equals(requested.getParameterTypes(), actual.getParameterTypes());
109+
}
110+
return false;
111+
}
112+
113+
public static Object forwardImplemented(Method requested, Object[] args) throws InvocationTargetException, NoSuchMethodException {
114+
final Method matchedMethod = matchMethod(requested);
115+
if(matchedMethod != null) {
116+
try {
117+
return matchedMethod.invoke(INSTANCE, args);
118+
} catch(IllegalAccessException e) {
119+
throw new RuntimeException(e);
120+
}
121+
}
122+
throw new NoSuchMethodException("Method not found: " + requested.getName());
123+
}
38124

39-
// reroute level checks to mojo logger
125+
/**
126+
* Interprets incoming method calls from one of the interfaces specified by CombinedLogger.
127+
* This is the main entry point for logging, if the consumer is unaware of this implementing class.
128+
*
129+
* @see CombinedLogger
130+
* @return varies based on the method called, null if void was expected
131+
* @throws Throwable dangerous!
132+
*/
133+
@Override
134+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
135+
/**
136+
* see if the current level is greater than the requested level
137+
* this isn't stupid. The library does a similar check
138+
* @see org.slf4j.Logger#isEnabledForLevel(Level)
139+
*/
40140
if(method.getName().matches("is(Trace|Debug|Info|Warn|Error)Enabled")) {
41141
final String levelName = method.getName().substring(2).toUpperCase();
42142
final int levelOrdinal = Level.valueOf(levelName).ordinal();
43-
return OUTPUT_LEVEL.ordinal() >= levelOrdinal;
143+
return OUTPUT_LEVEL.ordinal() <= levelOrdinal;
44144
}
45145

46146
if(method.getName().matches("trace|debug|info|warn|error")) {
47-
final String methodName = method.getName().replace("trace", "debug").toUpperCase();
48-
System.out.println("[" + methodName + "]" + formatIntercepted(method, args));
147+
log(Level.valueOf(method.getName().toUpperCase()), args);
49148
return null;
50149
}
51150

52-
System.out.println("Unhandled method: " + method.getName());
53-
return null;
151+
try {
152+
return forwardImplemented(method, args);
153+
} catch(InvocationTargetException e) {
154+
throw e.getCause();
155+
}
54156
}
55157

56-
public String formatIntercepted(Method method, Object[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
57-
if(args.length == 1)
58-
return args[0].toString();
158+
public static String format(Object[] args) {
159+
if(args.length == 0)
160+
return "";
161+
59162
args[0] = args[0].toString();
60-
if(args.length > 1 && args[1] instanceof Object[]) {
61-
return MessageFormatter.class.getMethod("arrayFormat", method.getParameterTypes()).invoke(null, args).toString();
163+
if(args.length == 1)
164+
return (String) args[0];
165+
166+
final FormattingTuple tuple;
167+
if(args.length == 2) {
168+
if(args[1] instanceof Object[]) {
169+
tuple = MessageFormatter.arrayFormat((String) args[0], (Object[]) args[1]);
170+
} else {
171+
tuple = MessageFormatter.format((String) args[0], args[1]);
172+
}
173+
} else if(args.length == 3) {
174+
if(args[1] instanceof Object[] && args[2] instanceof Throwable) {
175+
tuple = MessageFormatter.arrayFormat((String) args[0], (Object[]) args[1], (Throwable) args[2]);
176+
} else {
177+
tuple = MessageFormatter.format((String) args[0], args[1], args[2]);
178+
}
62179
} else {
63-
return MessageFormatter.class.getMethod("format", method.getParameterTypes()).invoke(null, args).toString();
180+
return Arrays.toString(args);
64181
}
182+
return tuple.getMessage();
65183
}
66184

67185
@Override

src/test/java/pl/project13/maven/git/FileSystemMavenSandbox.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
import javax.annotation.Nullable;
2626
import org.apache.commons.io.FileUtils;
2727
import org.apache.maven.project.MavenProject;
28-
import pl.project13.log.MavenLogger;
28+
import org.slf4j.event.Level;
29+
30+
import static pl.project13.log.MavenLogger.log;
2931

3032
/**
3133
* Quick and dirty maven projects tree structure to create on disk during integration tests. Can
@@ -74,8 +76,7 @@ public FileSystemMavenSandbox withChildProject(String childProjectDirName, Strin
7476

7577
@Nonnull
7678
public FileSystemMavenSandbox withGitRepoInParent(@Nonnull AvailableGitTestRepo repo) {
77-
MavenLogger.getLogger().info("Will prepare sandbox repository based on: [" + repo.getDir() + "]");
78-
MavenLogger.getLogger().info(MavenLogger.getLogger().getClass().getName());
79+
log(Level.INFO, "Will prepare sandbox repository based on: [" + repo.getDir() + "]");
7980
gitRepoSourceDir = repo.getDir();
8081
gitRepoTargetDir = parentProject.getBasedir();
8182
return this;

0 commit comments

Comments
 (0)