/***************************************************************************
* Copyright (C) by Fabrizio Montesi *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 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 Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
* For details about the authors of this software, see the AUTHORS file. *
***************************************************************************/
package joliex.lang;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import jolie.lang.Constants;
import jolie.ExecutionThread;
import jolie.Interpreter;
import jolie.lang.Constants.EmbeddedServiceType;
import jolie.net.CommListener;
import jolie.net.LocalCommChannel;
import jolie.net.ports.OutputPort;
import jolie.runtime.embedding.EmbeddedServiceLoader;
import jolie.runtime.embedding.EmbeddedServiceLoaderCreationException;
import jolie.runtime.embedding.EmbeddedServiceLoadingException;
import jolie.runtime.FaultException;
import jolie.runtime.InvalidIdException;
import jolie.runtime.JavaService;
import jolie.runtime.Value;
import jolie.runtime.ValuePrettyPrinter;
import jolie.runtime.VariablePath;
import jolie.runtime.VariablePathBuilder;
import jolie.runtime.embedding.RequestResponse;
public class RuntimeService extends JavaService
{
private final Interpreter interpreter;
public RuntimeService()
{
this.interpreter = Interpreter.getInstance();
}
public Value getLocalLocation()
{
Value v = Value.create();
v.setValue( interpreter.commCore().getLocalCommChannel() );
return v;
}
@RequestResponse
public void setMonitor( final Value request )
{
final VariablePath locationPath = new VariablePathBuilder( true )
.add( Constants.MONITOR_OUTPUTPORT_NAME, 0 )
.add( Constants.LOCATION_NODE_NAME, 0 ).toVariablePath();
locationPath.setValue( request.getFirstChild( Constants.LOCATION_NODE_NAME ) );
final VariablePath protocolPath = new VariablePathBuilder( true )
.add( Constants.MONITOR_OUTPUTPORT_NAME, 0 )
.add( Constants.PROTOCOL_NODE_NAME, 0 ).toVariablePath();
protocolPath.setValue( request.getFirstChild( Constants.PROTOCOL_NODE_NAME ) );
OutputPort port = new OutputPort(
interpreter(),
Constants.MONITOR_OUTPUTPORT_NAME,
locationPath,
protocolPath,
null,
true
);
port.optimizeLocation();
interpreter.setMonitor( port );
}
@RequestResponse
public void setOutputPort( Value request )
{
String name = request.getFirstChild( "name" ).strValue();
Value locationValue = request.getFirstChild( "location" );
Value protocolValue = request.getFirstChild( "protocol" );
OutputPort port =
new OutputPort(
interpreter(),
name
);
Value l;
Value r = interpreter.initThread().state().root();
l = r.getFirstChild( name ).getFirstChild( Constants.LOCATION_NODE_NAME );
if ( locationValue.isChannel() ) {
l.setValue( locationValue.channelValue() );
} else {
l.setValue( locationValue.strValue() );
}
r.getFirstChild( name ).getFirstChild( Constants.PROTOCOL_NODE_NAME ).refCopy( protocolValue );
r = ExecutionThread.currentThread().state().root();
l = r.getFirstChild( name ).getFirstChild( Constants.LOCATION_NODE_NAME );
if ( locationValue.isChannel() ) {
l.setValue( locationValue.channelValue() );
} else {
l.setValue( locationValue.strValue() );
}
r.getFirstChild( name ).getFirstChild( Constants.PROTOCOL_NODE_NAME ).deepCopy( protocolValue );
interpreter.register( name, port );
}
@RequestResponse
public void removeOutputPort( String outputPortName )
{
interpreter.removeOutputPort( outputPortName );
}
@RequestResponse
public void setRedirection( Value request )
throws FaultException
{
String serviceName = request.getChildren( "inputPortName" ).first().strValue();
CommListener listener =
interpreter.commCore().getListenerByInputPortName( serviceName );
if ( listener == null )
throw new FaultException( "RuntimeException", "Unknown inputPort: " + serviceName );
String resourceName = request.getChildren( "resourceName" ).first().strValue();
String opName = request.getChildren( "outputPortName" ).first().strValue();
try {
OutputPort port = interpreter.getOutputPort( opName );
listener.inputPort().redirectionMap().put( resourceName, port );
} catch( InvalidIdException e ) {
throw new FaultException( "RuntimeException", e );
}
}
@RequestResponse
public void removeRedirection( Value request )
throws FaultException
{
String serviceName = request.getChildren( "inputPortName" ).first().strValue();
CommListener listener =
interpreter.commCore().getListenerByInputPortName( serviceName );
if ( listener == null )
throw new FaultException( "RuntimeException", "Unknown inputPort: " + serviceName );
String resourceName = request.getChildren( "resourceName" ).first().strValue();
listener.inputPort().redirectionMap().remove( resourceName );
}
public Value getRedirection( Value request )
throws FaultException
{
Value ret = null;
String inputPortName = request.getChildren( "inputPortName" ).first().strValue();
CommListener listener =
interpreter.commCore().getListenerByInputPortName( inputPortName );
if ( listener == null ) {
throw new FaultException( "RuntimeException", Value.create( "Invalid input port: " + inputPortName ) );
}
String resourceName = request.getChildren( "resourceName" ).first().strValue();
OutputPort p = listener.inputPort().redirectionMap().get( resourceName );
if ( p == null ) {
ret = Value.create();
} else {
ret = Value.create( p.id() );
}
return ret;
}
public Value getIncludePaths()
{
Value ret = Value.create();
String[] includePaths = interpreter.includePaths();
for( String path : includePaths ) {
ret.getNewChild( "path" ).setValue( path );
}
return ret;
}
public Value loadEmbeddedService( Value request )
throws FaultException
{
try {
Value channel = Value.create();
String filePath = request.getFirstChild( "filepath" ).strValue();
String typeStr = request.getFirstChild( "type" ).strValue();
EmbeddedServiceType type =
jolie.lang.Constants.stringToEmbeddedServiceType( typeStr );
EmbeddedServiceLoader loader =
EmbeddedServiceLoader.create( interpreter(), type, filePath, channel );
loader.load();
return channel;
} catch( EmbeddedServiceLoaderCreationException e ) {
e.printStackTrace();
throw new FaultException( "RuntimeException", e );
} catch( EmbeddedServiceLoadingException e ) {
e.printStackTrace();
throw new FaultException( "RuntimeException", e );
}
}
@RequestResponse
public void loadLibrary( String libraryPath )
throws FaultException
{
try {
interpreter.getClassLoader().addJarResource( libraryPath );
} catch( IOException e ) {
throw new FaultException( "IOException", e );
} catch( IllegalArgumentException e ) {
throw new FaultException( "IOException", e );
}
}
@RequestResponse
public void callExit( Value request )
{
Object o = request.valueObject();
if ( o instanceof LocalCommChannel ) {
((LocalCommChannel)o).interpreter().exit();
}
}
public String dumpState()
{
Writer writer = new StringWriter();
ValuePrettyPrinter printer = new ValuePrettyPrinter( Value.createDeepCopy( interpreter.globalValue() ), writer, "Global state" );
try {
printer.run();
printer = new ValuePrettyPrinter( Value.createDeepCopy( ExecutionThread.currentThread().state().root() ), writer, "Session state" );
printer.run();
} catch( IOException e ) {} // Should never happen
return writer.toString();
}
}