/***************************************************************************
* Copyright (C) 2011 by Fabrizio Montesi <famontesi@gmail.com> *
* *
* 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 jolie.runtime.correlation;
import jolie.Interpreter;
import jolie.SessionListener;
import jolie.SessionThread;
import jolie.net.CommChannel;
import jolie.net.CommMessage;
import jolie.runtime.Value;
import jolie.runtime.correlation.CorrelationSet.CorrelationPair;
import jolie.runtime.correlation.impl.SimpleCorrelationEngine;
/**
* Generic abstract class for correlation algorithm implementations.
* @author Fabrizio Montesi
*/
public abstract class CorrelationEngine implements SessionListener
{
public enum Type {
SIMPLE {
public CorrelationEngine createInstance( Interpreter interpreter ) {
return new SimpleCorrelationEngine( interpreter );
}
},
HASH {
public CorrelationEngine createInstance( Interpreter interpreter ) {
//return new HashCorrelationEngine( interpreter );
return null;
}
};
public abstract CorrelationEngine createInstance( Interpreter interpreter );
public static Type fromString( String name )
{
if ( "simple".equals( name ) ) {
return SIMPLE;
} else if ( "hash".equals( name ) ) {
return HASH;
}
return null;
}
}
public abstract void onSessionStart( SessionThread session, Interpreter.SessionStarter starter, CommMessage message );
public abstract void onSingleExecutionSessionStart( SessionThread session );
public abstract boolean routeMessage( CommMessage message, CommChannel channel );
private final Interpreter interpreter;
public CorrelationEngine( Interpreter interpreter )
{
this.interpreter = interpreter;
}
protected Interpreter interpreter()
{
return interpreter;
}
protected void initCorrelationValues( SessionThread session, Interpreter.SessionStarter starter, CommMessage message )
{
Value messageValue;
CorrelationSet correlationSet = starter.correlationInitializer();
if ( correlationSet == null ) { // TODO check this w.r.t. the type system
return;
}
for( CorrelationPair pair : starter.correlationInitializer().getOperationCorrelationPairs( starter.guard().inputOperation().id() ) ) {
messageValue = pair.messagePath().getValueOrNull( message.value() );
if ( messageValue == null ) {
messageValue = Value.create();
}
pair.sessionPath().getValue( session.state().root() ).assignValue( messageValue );
}
}
public synchronized void onMessageReceive( final CommMessage message, final CommChannel channel )
throws CorrelationError
{
if ( routeMessage( message, channel ) ) {
return;
}
// We did not find any correlating session
if ( interpreter.startServiceSession( message, channel ) ) {
return;
}
// We can not handle the message, send an error to the invoker
throw new CorrelationError();
}
}