/*
ESXX - The friendly ECMAscript/XML Application Server
Copyright (C) 2007-2015 Martin Blom <martin@blom.org>
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.esxx.js;
import org.esxx.Application;
import org.esxx.Request;
import java.util.logging.*;
import org.mozilla.javascript.*;
public class JSLogger
extends ScriptableObject {
private static final long serialVersionUID = -6547957908255929015L;
public JSLogger() {
super();
}
public JSLogger(Application app, Request request, Logger logger, String ident) {
super();
this.app = app;
this.req = request;
this.logger = logger;
this.ident = ident;
this.lastLevel = null;
}
public static JSLogger newJSLogger(Context cx, Application app) {
return (JSLogger) JSESXX.newObject(cx, app.getJSGlobal(), "Logger",
new Object[] { app, app.getAppName() });
}
public static Object jsConstructor(Context cx,
java.lang.Object[] args,
Function ctorObj,
boolean inNewExpr) {
Application app = null;
Request req = null;
Logger logger = null;
String ident = null;
if (args.length >= 1) {
if (args[0] instanceof Application) {
app = (Application) args[0];
}
else if (args[0] instanceof Request) {
req = (Request) args[0];
}
else if (args[0] instanceof Logger) {
logger = (Logger) args[0];
}
else {
throw Context.reportRuntimeError("Invalid first argument");
}
}
else {
throw Context.reportRuntimeError("Missing argument");
}
if (args.length >= 2 && args[1] != Context.getUndefinedValue()) {
ident = Context.toString(args[1]);
}
return new JSLogger(app, req, logger, ident);
}
public static void finishInit(Scriptable scope,
FunctionObject constructor,
Scriptable prototype) {
// Create and make the "level" property in the prototype visible
ScriptableObject.defineProperty(prototype, "level", "debug", ScriptableObject.PERMANENT);
}
@Override
public String getClassName() {
return "Logger";
}
public void jsFunction_debug(String msg) {
log(Level.FINE, msg);
}
public void jsFunction_info(String msg) {
log(Level.INFO, msg);
}
public void jsFunction_warn(String msg) {
log(Level.WARNING, msg);
}
public void jsFunction_error(String msg) {
log(Level.SEVERE, msg);
}
private synchronized void log(Level level, String msg) {
if (logger == null) {
if (app != null) {
logger = app.getAppLogger();
}
else if (req != null) {
logger = req.getReqLogger();
}
else {
throw new IllegalStateException("Expected non-null Application or Request object");
}
}
Object new_level_obj = ScriptableObject.getProperty(this, "level");
if (new_level_obj != lastLevel) {
String new_level = Context.toString(new_level_obj);
if ("debug".equals(new_level)) {
logger.setLevel(Level.FINE);
}
else if ("info".equals(new_level)) {
logger.setLevel(Level.INFO);
}
else if ("warn".equals(new_level)) {
logger.setLevel(Level.WARNING);
}
else if ("error".equals(new_level)) {
logger.setLevel(Level.SEVERE);
}
else {
throw Context.reportRuntimeError("Level should be 'debug', 'info', 'warn' or 'error', "
+ "not '" + new_level + "'");
}
lastLevel = new_level_obj;
}
LogRecord lr = new LogRecord(level, msg);
lr.setSourceClassName(ident);
lr.setSourceMethodName(null);
logger.log(lr);
}
private Application app;
private Request req;
private Logger logger;
private String ident;
private Object lastLevel;
}