import org.simantics.scl.compiler.types.kinds.Kinds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
@Component
public class LoggingModule extends ConcreteModule {
- private static String[] LOGGING_METHODS = new String[] {
+ private static final String[] LOGGING_METHODS = new String[] {
"trace", "debug", "info", "warn", "error"
};
public static final TCon Throwable = Types.con("Prelude", "Throwable");
public LoggingModule() {
- super("Logging");
-
+ super("LoggingJava");
+
// Logger
TCon Logger = Types.con(getName(), "Logger");
StandardTypeConstructor loggerConstructor = new StandardTypeConstructor(Logger, Kinds.STAR, TypeDesc.forClass(Logger.class));
loggerConstructor.external = true;
addTypeDescriptor("Logger", loggerConstructor);
+ // Marker
+ TCon Marker = Types.con(getName(), "Marker");
+ StandardTypeConstructor markerConstructor = new StandardTypeConstructor(Marker, Kinds.STAR, TypeDesc.forClass(Marker.class));
+ markerConstructor.external = true;
+ addTypeDescriptor("Marker", markerConstructor);
+
// Common types
+ Type isEnabledType = Types.functionE(Types.PUNIT, Types.PROC, Types.BOOLEAN);
Type loggingType = Types.functionE(Types.STRING, Types.PROC, Types.UNIT);
+ Type loggingTypeWithMarker = Types.functionE(new Type[] { Marker, Types.STRING }, Types.PROC, Types.UNIT);
Type loggingTypeWithException = Types.functionE(new Type[] { Types.STRING, Throwable }, Types.PROC, Types.UNIT);
+ Type loggingTypeWithMarkerAndException = Types.functionE(new Type[] { Marker, Types.STRING, Throwable }, Types.PROC, Types.UNIT);
// Add logging methods
for(String methodName : LOGGING_METHODS) {
- {
+ { // isEnabled :: <Proc> Boolean
+ String completeMethodName = generateIsEnabledName(methodName);
+ JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", completeMethodName, Types.PROC, Types.BOOLEAN, Logger);
+ SCLValue value = new SCLValue(Name.create(getName(), completeMethodName));
+ value.setType(isEnabledType);
+ value.setMacroRule(new MacroRule() {
+ @Override
+ public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ ConcreteModule module = context.getCompilationContext().module;
+ String identifier;
+ if (module != null)
+ identifier = module.getName().replaceAll("/", ".");
+ else
+ identifier = CommandSession.class.getName();
+ apply.set(new ELiteral(javaMethod), new Expression[] {
+ new EExternalConstant(LoggerFactory.getLogger(identifier), Logger)
+ });
+ return apply;
+ }
+ });
+ addValue(value);
+ }
+ { // logging function with single String-parameter :: String -> <Proc> ()
JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", methodName, Types.PROC, Types.UNIT, Logger, Types.STRING);
SCLValue value = new SCLValue(Name.create(getName(), methodName));
value.setType(loggingType);
});
addValue(value);
}
- {
+ { // logging function with two parameters :: String -> Throwable -> <Proc> ()
JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", methodName, Types.PROC, Types.UNIT, Logger, Types.STRING, Throwable);
SCLValue value = new SCLValue(Name.create(getName(), methodName + "E"));
value.setType(loggingTypeWithException);
});
addValue(value);
}
+ { // logging function with two parameters :: Marker -> String -> <Proc> ()
+ JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", methodName, Types.PROC, Types.UNIT, Logger, Marker, Types.STRING);
+ SCLValue value = new SCLValue(Name.create(getName(), methodName + "M"));
+ value.setType(loggingTypeWithMarker);
+ value.setMacroRule(new MacroRule() {
+ @Override
+ public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ ConcreteModule module = context.getCompilationContext().module;
+ String identifier;
+ if (module != null)
+ identifier = module.getName().replaceAll("/", ".");
+ else
+ identifier = CommandSession.class.getName();
+ apply.set(new ELiteral(javaMethod), new Expression[] {
+ new EExternalConstant(LoggerFactory.getLogger(identifier), Logger),
+ apply.parameters[0],
+ apply.parameters[1]
+ });
+ return apply;
+ }
+ });
+ addValue(value);
+ }
+ { // logging function with three parameters :: Marker -> String -> Throwable -> <Proc> ()
+ JavaMethod javaMethod = new JavaMethod(false, "org/slf4j/Logger", methodName, Types.PROC, Types.UNIT, Logger, Marker, Types.STRING, Throwable);
+ SCLValue value = new SCLValue(Name.create(getName(), methodName + "ME"));
+ value.setType(loggingTypeWithMarkerAndException);
+ value.setMacroRule(new MacroRule() {
+ @Override
+ public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ ConcreteModule module = context.getCompilationContext().module;
+ String identifier;
+ if (module != null)
+ identifier = module.getName().replaceAll("/", ".");
+ else
+ identifier = CommandSession.class.getName();
+ apply.set(new ELiteral(javaMethod), new Expression[] {
+ new EExternalConstant(LoggerFactory.getLogger(identifier), Logger),
+ apply.parameters[0],
+ apply.parameters[1],
+ apply.parameters[2]
+ });
+ return apply;
+ }
+ });
+ addValue(value);
+ }
}
setParentClassLoader(LoggerFactory.class.getClassLoader());
}
+ private static String generateIsEnabledName(String level) {
+ return "is" + capitalizeFirstCharacter(level) + "Enabled";
+ }
+
+ private static String capitalizeFirstCharacter(String input) {
+ return input.substring(0, 1).toUpperCase() + input.substring(1);
+ }
}