/**
* eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the
* <e-UCM> research group.
*
* Copyright 2005-2010 <e-UCM> research group.
*
* You can access a list of all the contributors to eAdventure at:
* http://e-adventure.e-ucm.es/contributors
*
* <e-UCM> is a research group of the Department of Software Engineering
* and Artificial Intelligence at the Complutense University of Madrid
* (School of Computer Science).
*
* C Profesor Jose Garcia Santesmases sn,
* 28040 Madrid (Madrid), Spain.
*
* For more info please visit: <http://e-adventure.e-ucm.es> or
* <http://www.e-ucm.es>
*
* ****************************************************************************
*
* This file is part of eAdventure, version 2.0
*
* eAdventure is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* eAdventure 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with eAdventure. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package es.eucm.ead.editor.control;
import es.eucm.ead.editor.view.components.OutputLogPanel;
import es.eucm.ead.tools.java.utils.FileUtils;
import java.io.IOException;
import java.io.Writer;
import static java.lang.System.out;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author mfreire
*/
public class ScriptControllerImpl implements ScriptController {
private static Logger logger = LoggerFactory
.getLogger(ScriptControllerImpl.class);
private ScriptEngineManager mgr = new ScriptEngineManager();
private ScriptEngine jsEngine;
private Controller controller;
public ScriptControllerImpl() {
jsEngine = mgr.getEngineByName("JavaScript");
ScriptContext sc = jsEngine.getContext();
sc.setWriter(new Writer() {
private StringBuilder sb = new StringBuilder();
private Logger jsLog = LoggerFactory.getLogger("js");
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
sb.append(cbuf, off, len);
}
@Override
public void flush() throws IOException {
jsLog.info(sb.toString());
sb.setLength(0);
}
@Override
public void close() throws IOException {
}
});
}
@Override
public ScriptContext getContext() {
return jsEngine.getContext();
}
@Override
public void refreshScripts() {
logger.info("Refreshing scripts...");
Bindings b = jsEngine.createBindings();
b.put("controller", controller);
jsEngine.setBindings(b, ScriptContext.GLOBAL_SCOPE);
try {
String r = FileUtils.loadResourceToString("/scripts/env.js");
eval(r, null, getContext(), "refresh");
} catch (IOException ex) {
logger.warn("Error reading resource", ex);
}
}
@Override
public Object eval(String script, OutputLogPanel out,
ScriptContext context, String source) {
try {
long ms = System.currentTimeMillis();
Object output = jsEngine.eval(script, context);
ms = System.currentTimeMillis() - ms;
if (out != null) {
out.append("Evaluated " + script.length() + " chars from "
+ source + " in " + ms + " ms:", "");
out.append(" -- ", (output == null) ? "(null)" : output
.toString());
} else {
logger.info("Evaluated {} chars from {} in {} ms: {}", script
.length(), source, ms, output);
}
return output;
} catch (ScriptException ex) {
Throwable c = ex.getCause();
while (c != null && !(c.getClass().getName().endsWith("EcmaError"))) {
c = c.getCause();
}
String error = (c == null ? ex.getMessage() : c.getMessage());
if (out != null) {
out.append(" E ", error);
logger.info(error, ex);
} else {
logger.info(" E " + error, ex);
}
return null;
}
}
/**
* Set the actual super-controller.
* @param controller the main controller, providing access to model, views,
* and more
*/
@Override
public void setController(Controller controller) {
this.controller = controller;
refreshScripts();
}
}