Add slf4j support

This commit is contained in:
konsoletyper 2015-03-08 19:32:01 +03:00
parent 4f508954d0
commit bcf0929fc5
9 changed files with 560 additions and 0 deletions

View File

@ -83,6 +83,7 @@
<module>teavm-cli</module>
<module>teavm-chrome-rdp</module>
<module>teavm-tests</module>
<module>teavm-extras-slf4j</module>
</modules>
<dependencyManagement>

4
teavm-extras-slf4j/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/target/
/.settings/
/.classpath
/.project

View File

@ -0,0 +1,68 @@
<!--
Copyright 2015 Alexey Andreev.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.teavm</groupId>
<artifactId>teavm</artifactId>
<version>0.3.0-SNAPSHOT</version>
</parent>
<artifactId>teavm-extras-slf4j</artifactId>
<name>TeaVM slf4j</name>
<description>TeaVM backend for slf4j</description>
<dependencies>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-jso</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>../checkstyle.xml</configLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,81 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.extras.slf4j;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.*;
import org.teavm.model.instructions.*;
/**
*
* @author Alexey Andreev
*/
public class LoggerFactoryTransformer implements ClassHolderTransformer {
@Override
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
if (!cls.getName().equals(LoggerFactory.class.getName())) {
return;
}
addCacheField(cls);
modifyClinit(cls);
replaceGetFactory(cls);
}
private void addCacheField(ClassHolder cls) {
FieldHolder cacheField = new FieldHolder("loggerFactoryCache");
cacheField.setLevel(AccessLevel.PRIVATE);
cacheField.getModifiers().add(ElementModifier.STATIC);
cacheField.setType(ValueType.object(TeaVMLoggerFactory.class.getName()));
cls.addField(cacheField);
}
private void modifyClinit(ClassHolder cls) {
MethodHolder clinit = cls.getMethod(new MethodDescriptor("<clinit>", void.class));
BasicBlock clinitBlock = clinit.getProgram().basicBlockAt(0);
Variable factoryVar = clinit.getProgram().createVariable();
ConstructInstruction construct = new ConstructInstruction();
construct.setType(TeaVMLoggerFactory.class.getName());
construct.setReceiver(factoryVar);
clinitBlock.getInstructions().add(0, construct);
InvokeInstruction init = new InvokeInstruction();
init.setInstance(factoryVar);
init.setMethod(new MethodReference(TeaVMLoggerFactory.class, "<init>", void.class));
init.setType(InvocationType.SPECIAL);
clinitBlock.getInstructions().add(1, init);
PutFieldInstruction put = new PutFieldInstruction();
put.setValue(factoryVar);
put.setField(new FieldReference(LoggerFactory.class.getName(), "loggerFactoryCache"));
clinitBlock.getInstructions().add(2, put);
}
private void replaceGetFactory(ClassHolder cls) {
MethodHolder method = cls.getMethod(new MethodDescriptor("getILoggerFactory", ILoggerFactory.class));
Program program = new Program();
BasicBlock block = program.createBasicBlock();
Variable cacheVar = program.createVariable();
GetFieldInstruction get = new GetFieldInstruction();
get.setField(new FieldReference(LoggerFactory.class.getName(), "loggerFactoryCache"));
get.setFieldType(ValueType.object(ILoggerFactory.class.getName()));
get.setReceiver(cacheVar);
block.getInstructions().add(get);
ExitInstruction exit = new ExitInstruction();
exit.setValueToReturn(cacheVar);
block.getInstructions().add(exit);
method.setProgram(program);
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.extras.slf4j;
import org.teavm.vm.spi.TeaVMHost;
import org.teavm.vm.spi.TeaVMPlugin;
/**
*
* @author Alexey Andreev
*/
public class Slf4jPlugin implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
host.add(new LoggerFactoryTransformer());
}
}

View File

@ -0,0 +1,335 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.extras.slf4j;
import org.slf4j.Logger;
import org.slf4j.Marker;
/**
*
* @author Alexey Andreev
*/
public class TeaVMLogger implements Logger {
private String name;
public TeaVMLogger(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public boolean isTraceEnabled() {
return false;
}
@Override
public void trace(String msg) {
}
@Override
public void trace(String format, Object arg) {
}
@Override
public void trace(String format, Object arg1, Object arg2) {
}
@Override
public void trace(String format, Object... arguments) {
}
@Override
public void trace(String msg, Throwable t) {
}
@Override
public boolean isTraceEnabled(Marker marker) {
return false;
}
@Override
public void trace(Marker marker, String msg) {
}
@Override
public void trace(Marker marker, String format, Object arg) {
}
@Override
public void trace(Marker marker, String format, Object arg1, Object arg2) {
}
@Override
public void trace(Marker marker, String format, Object... argArray) {
}
@Override
public void trace(Marker marker, String msg, Throwable t) {
}
@Override
public boolean isDebugEnabled() {
return false;
}
@Override
public void debug(String msg) {
}
@Override
public void debug(String format, Object arg) {
}
@Override
public void debug(String format, Object arg1, Object arg2) {
}
@Override
public void debug(String format, Object... arguments) {
}
@Override
public void debug(String msg, Throwable t) {
}
@Override
public boolean isDebugEnabled(Marker marker) {
return false;
}
@Override
public void debug(Marker marker, String msg) {
}
@Override
public void debug(Marker marker, String format, Object arg) {
}
@Override
public void debug(Marker marker, String format, Object arg1, Object arg2) {
}
@Override
public void debug(Marker marker, String format, Object... arguments) {
}
@Override
public void debug(Marker marker, String msg, Throwable t) {
}
@Override
public boolean isInfoEnabled() {
return true;
}
private void log(String level, String format, Object... arguments) {
StringBuffer sb = new StringBuffer();
sb.append('[').append(level).append("] ").append(name).append(": ");
int index = 0;
int argIndex = 0;
while (index < format.length()) {
int next = format.indexOf("{}", index);
if (next == -1) {
break;
}
sb.append(format.subSequence(index, next));
sb.append(argIndex < arguments.length ? String.valueOf(arguments[argIndex]) : "{}");
index = next + 2;
++argIndex;
}
sb.append(format.substring(index));
System.err.println(sb);
}
@Override
public void info(String msg) {
info(msg, new Object[0]);
}
@Override
public void info(String format, Object arg) {
info(format, new Object[] { arg });
}
@Override
public void info(String format, Object arg1, Object arg2) {
info(format, new Object[] { arg1, arg2 });
}
@Override
public void info(String format, Object... arguments) {
log("INFO", format, arguments);
}
@Override
public void info(String msg, Throwable t) {
info(msg);
}
@Override
public boolean isInfoEnabled(Marker marker) {
return true;
}
@Override
public void info(Marker marker, String msg) {
info(msg);
}
@Override
public void info(Marker marker, String format, Object arg) {
info(format, arg);
}
@Override
public void info(Marker marker, String format, Object arg1, Object arg2) {
info(format, arg1, arg2);
}
@Override
public void info(Marker marker, String format, Object... arguments) {
info(format, arguments);
}
@Override
public void info(Marker marker, String msg, Throwable t) {
info(msg, t);
}
@Override
public boolean isWarnEnabled() {
return true;
}
@Override
public void warn(String msg) {
warn(msg, new Object[0]);
}
@Override
public void warn(String format, Object arg) {
warn(format, new Object[] { arg });
}
@Override
public void warn(String format, Object... arguments) {
log("WARN", format, arguments);
}
@Override
public void warn(String format, Object arg1, Object arg2) {
warn(format, new Object[] { arg1, arg2 });
}
@Override
public void warn(String msg, Throwable t) {
warn(msg);
}
@Override
public boolean isWarnEnabled(Marker marker) {
return true;
}
@Override
public void warn(Marker marker, String msg) {
warn(msg);
}
@Override
public void warn(Marker marker, String format, Object arg) {
warn(format, arg);
}
@Override
public void warn(Marker marker, String format, Object arg1, Object arg2) {
warn(format, arg1, arg2);
}
@Override
public void warn(Marker marker, String format, Object... arguments) {
warn(format, arguments);
}
@Override
public void warn(Marker marker, String msg, Throwable t) {
warn(msg, t);
}
@Override
public boolean isErrorEnabled() {
return true;
}
@Override
public void error(String msg) {
error(msg, new Object[0]);
}
@Override
public void error(String format, Object arg) {
error(format, new Object[] { arg });
}
@Override
public void error(String format, Object arg1, Object arg2) {
error(format, new Object[] { arg1, arg2 });
}
@Override
public void error(String format, Object... arguments) {
log("ERRO", format, arguments);
}
@Override
public void error(String msg, Throwable t) {
error(msg);
}
@Override
public boolean isErrorEnabled(Marker marker) {
return true;
}
@Override
public void error(Marker marker, String msg) {
error(msg);
}
@Override
public void error(Marker marker, String format, Object arg) {
error(format, arg);
}
@Override
public void error(Marker marker, String format, Object arg1, Object arg2) {
error(format, arg1, arg2);
}
@Override
public void error(Marker marker, String format, Object... arguments) {
error(format, arguments);
}
@Override
public void error(Marker marker, String msg, Throwable t) {
error(msg, t);
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2015 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.extras.slf4j;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
/**
*
* @author Alexey Andreev
*/
public class TeaVMLoggerFactory implements ILoggerFactory {
private Map<String, TeaVMLogger> loggers = new HashMap<>();
@Override
public Logger getLogger(String name) {
TeaVMLogger logger = loggers.get(name);
if (logger == null) {
logger = new TeaVMLogger(name);
loggers.put(name, logger);
}
return logger;
}
}

View File

@ -0,0 +1 @@
org.teavm.extras.slf4j.Slf4jPlugin

View File

@ -33,6 +33,7 @@
<groupId>org.teavm</groupId>
<artifactId>teavm-classlib</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>