/**
*
* Copyright
* 2009-2015 Jayway Products AB
* 2016-2017 Föreningen Sambruk
*
* Licensed under AGPL, Version 3.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.gnu.org/licenses/agpl.txt
*
* 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 se.streamsource.streamflow.web.application.console;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Map;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.qi4j.api.Qi4j;
import org.qi4j.api.injection.scope.Structure;
import org.qi4j.api.mixin.Mixins;
import org.qi4j.api.service.Activatable;
import org.qi4j.api.service.ServiceComposite;
import org.qi4j.api.structure.Module;
import org.qi4j.api.unitofwork.UnitOfWork;
import org.qi4j.api.usecase.UsecaseBuilder;
import org.qi4j.api.value.ValueBuilder;
import bsh.EvalError;
import bsh.Interpreter;
/**
* JAVADOC
*/
@Mixins(ConsoleService.Mixin.class)
public interface ConsoleService
extends Console, ServiceComposite
{
class Mixin
implements Activatable, Console
{
@Structure
Module module;
@Structure
Qi4j qi4j;
public void activate() throws Exception
{
}
public void passivate() throws Exception
{
}
public ConsoleResultValue executeScript( ConsoleScriptValue script ) throws Exception
{
if (script.language().get() == Console.Language.BEANSHELL)
{
return executeBeanshell( script );
}
return null;
}
private ConsoleResultValue executeBeanshell( ConsoleScriptValue script ) throws Exception
{
ValueBuilder<ConsoleResultValue> builder = module.valueBuilderFactory().newValueBuilder(ConsoleResultValue.class);
Interpreter interpreter = new Interpreter();
// Bind default stuff
UnitOfWork unitOfWork = module.unitOfWorkFactory().newUnitOfWork(UsecaseBuilder.newUsecase("Script"));
interpreter.set( "uow", unitOfWork );
interpreter.set( "query", module.queryBuilderFactory() );
interpreter.set( "services", module.serviceFinder() );
interpreter.set( "qi4j", qi4j );
// Import commands
interpreter.eval( "importCommands(\"se.streamsource.streamflow.web.application.console.commands\");" );
// Bind given values
for (Map.Entry<String, Object> entry : script.bindings().get().entrySet())
{
interpreter.set( entry.getKey(), entry.getValue() );
}
// Replace output streams
ByteArrayOutputStream stream = new ByteArrayOutputStream();
PrintStream out = new PrintStream( stream, true, "UTF-8" );
interpreter.setOut( out );
interpreter.setErr( out );
// Add log handler
Logger root = Logger.getLogger( "" );
final List<LogRecord> log = builder.prototype().log().get();
Handler handler = new Handler()
{
public void publish( LogRecord record )
{
log.add( record );
}
public void flush()
{
}
public void close() throws SecurityException
{
}
};
root.addHandler( handler );
// Eval script
try
{
interpreter.eval( script.script().get() );
builder.prototype().out().set( new String( stream.toByteArray(), "UTF-8" ) );
if (script.completeUnitOfWork().get())
{
unitOfWork.complete();
} else
{
unitOfWork.discard();
}
} catch (EvalError evalError)
{
evalError.printStackTrace();
builder.prototype().out().set( evalError.toString() );
} finally
{
// Remove handler
root.removeHandler( handler );
}
return builder.newInstance();
}
}
}