Adds partial implementation of JCL logger framework

This commit is contained in:
konsoletyper 2014-02-23 19:39:25 +04:00
parent 45dc8aa0ec
commit 6e4e66c759
5 changed files with 405 additions and 0 deletions

View File

@ -73,4 +73,8 @@ public class TThread extends TObject implements TRunnable {
public static int activeCount() {
return 1;
}
public long getId() {
return 1;
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2014 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.classlib.java.util.logging;
import java.io.IOException;
import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class LoggerNativeGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
writer.append("if (console) {").indent().softNewLine();
writer.append("console.").append(methodRef.getName()).append("(").append(context.getParameterName(1))
.append(");").softNewLine();
writer.outdent().append("}").softNewLine();
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2014 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.classlib.java.util.logging;
import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.TInteger;
import org.teavm.classlib.java.lang.TObject;
import org.teavm.classlib.java.lang.TString;
import org.teavm.javascript.ni.Rename;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TLevel extends TObject implements TSerializable {
public static final TLevel OFF = new TLevel(TString.wrap("OFF"), TInteger.MAX_VALUE);
public static final TLevel SEVERE = new TLevel(TString.wrap("SEVERE"), 1000);
public static final TLevel WARNING = new TLevel(TString.wrap("WARNING"), 900);
public static final TLevel INFO = new TLevel(TString.wrap("INFO"), 800);
public static final TLevel CONFIG = new TLevel(TString.wrap("CONFIG"), 700);
public static final TLevel FINE = new TLevel(TString.wrap("FINE"), 500);
public static final TLevel FINER = new TLevel(TString.wrap("FINER"), 400);
public static final TLevel FINEST = new TLevel(TString.wrap("FINEST"), 300);
public static final TLevel ALL = new TLevel(TString.wrap("FINEST"), TInteger.MIN_VALUE);
private TString name;
private int value;
protected TLevel(TString name, int value) {
this.name = name;
this.value = value;
}
public TString getName() {
return name;
}
@Override
@Rename("toString")
public final TString toString0() {
return name;
}
public final int intValue() {
return value;
}
}

View File

@ -0,0 +1,125 @@
/*
* Copyright 2014 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.classlib.java.util.logging;
import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.*;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TLogRecord extends TObject implements TSerializable {
private static long sequenceNumberGenerator;
private TLevel level;
private TString loggerName;
private TString message;
private long millis;
private Object[] parameters;
private long sequenceNumber;
private TString sourceClassName;
private TString sourceMethodName;
private long threadID;
private TThrowable thrown;
public TLogRecord(TLevel level, TString msg) {
this.level = level;
this.message = msg;
this.millis = TSystem.currentTimeMillis();
this.sequenceNumber = sequenceNumberGenerator++;
this.threadID = TThread.currentThread().getId();
}
public TLevel getLevel() {
return level;
}
public void setLevel(TLevel level) {
this.level = level;
}
public TString getLoggerName() {
return loggerName;
}
public void setLoggerName(TString loggerName) {
this.loggerName = loggerName;
}
public TString getMessage() {
return message;
}
public void setMessage(TString message) {
this.message = message;
}
public long getMillis() {
return millis;
}
public void setMillis(long millis) {
this.millis = millis;
}
public Object[] getParameters() {
return parameters;
}
public void setParameters(Object[] parameters) {
this.parameters = parameters;
}
public long getSequenceNumber() {
return sequenceNumber;
}
public void setSequenceNumber(long sequenceNumber) {
this.sequenceNumber = sequenceNumber;
}
public TString getSourceClassName() {
return sourceClassName;
}
public void setSourceClassName(TString sourceClassName) {
this.sourceClassName = sourceClassName;
}
public TString getSourceMethodName() {
return sourceMethodName;
}
public void setSourceMethodName(TString sourceMethodName) {
this.sourceMethodName = sourceMethodName;
}
public long getThreadID() {
return threadID;
}
public void setThreadID(long threadID) {
this.threadID = threadID;
}
public TThrowable getThrown() {
return thrown;
}
public void setThrown(TThrowable thrown) {
this.thrown = thrown;
}
}

View File

@ -0,0 +1,181 @@
/*
* Copyright 2014 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.classlib.java.util.logging;
import org.teavm.classlib.java.lang.*;
import org.teavm.classlib.java.util.THashMap;
import org.teavm.classlib.java.util.TMap;
import org.teavm.javascript.ni.GeneratedBy;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TLogger {
public static final TString GLOBAL_LOGGER_NAME = TString.wrap("global");
private static TMap<TString, TLogger> loggerCache = new THashMap<>();
private TString name;
private TLogger parent;
TLogger(TString name) {
this.name = name;
}
public static TLogger getLogger(TString name) {
TLogger logger = loggerCache.get(name);
if (logger == null) {
logger = new TLogger(name);
int dotIndex = name.lastIndexOf('.');
if (dotIndex >= 0) {
TString parentName = name.substring(0, dotIndex);
logger.parent = getLogger(parentName);
} else if (!name.isEmpty()) {
logger.parent = getLogger(TString.wrap(""));
}
loggerCache.put(name, logger);
}
return logger;
}
public static TLogger getAnonymousLogger() {
return new TLogger(null);
}
public void log(TLogRecord record) {
TString message = format(record.getMessage(), record.getParameters());
if (record.getLevel().intValue() >= TLevel.SEVERE.intValue()) {
error(message);
} else if (record.getLevel().intValue() >= TLevel.WARNING.intValue()) {
warn(message);
} else {
info(message);
}
}
private TString format(TString message, Object[] params) {
if (params == null) {
return message;
}
TStringBuilder sb = new TStringBuilder();
int index = 0;
while (index < message.length()) {
int next = message.indexOf('{', index);
if (next < 0) {
break;
}
int paramStart = next + 1;
next = digits(paramStart, message);
if (next < 0) {
break;
}
if (message.charAt(next) != '}') {
sb.append(message.substring(index, next));
index = next;
continue;
}
int paramIndex = TInteger.parseInt(message.substring(index, next - 1));
if (paramIndex >= params.length) {
sb.append(message.substring(index, next));
index = next;
continue;
}
sb.append(TObject.wrap(params[paramIndex]));
index = next + 1;
}
return TString.wrap(sb.toString());
}
private static int digits(int from, TString message) {
while (from < message.length()) {
int c = message.charAt(from++);
if (c <= '0' || c >= '9') {
return from;
}
}
return -1;
}
public void log(TLevel level, TString msg, Object[] params) {
TLogRecord record = new TLogRecord(level, msg);
record.setParameters(params);
log(record);
}
public void log(TLevel level, TString msg) {
log(new TLogRecord(level, msg));
}
public void log(TLevel level, TString msg, TObject param1) {
TLogRecord record = new TLogRecord(level, msg);
record.setParameters(new Object[] { param1 });
log(record);
}
public void log(TLevel level, TString msg, TThrowable thrown) {
TLogRecord record = new TLogRecord(level, msg);
record.setThrown(thrown);
log(record);
}
public void severe(TString msg) {
log(TLevel.SEVERE, msg);
}
public void warning(TString msg) {
log(TLevel.WARNING, msg);
}
public void config(TString msg) {
log(TLevel.CONFIG, msg);
}
public void fine(TString msg) {
log(TLevel.FINE, msg);
}
public void finer(TString msg) {
log(TLevel.FINER, msg);
}
public void finest(TString msg) {
log(TLevel.FINEST, msg);
}
public boolean isLoggable(@SuppressWarnings("unused") TLevel level) {
return true;
}
public TString getName() {
return name;
}
public TLogger getParent() {
return parent;
}
public void setParent(TLogger parent) {
this.parent = parent;
}
@GeneratedBy(LoggerNativeGenerator.class)
public native void info(TString message);
@GeneratedBy(LoggerNativeGenerator.class)
private native void warn(TString message);
@GeneratedBy(LoggerNativeGenerator.class)
private native void error(TString message);
}