package org.nuunframework.ensemble.engine; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; import java.util.Stack; import java.util.concurrent.ConcurrentHashMap; import org.nuunframework.ensemble.Ensemble; @SuppressWarnings("rawtypes") public class EnsemblePlayer implements Runnable { private final EnsembleRecording playerRecording; private final Map<String, Object> globalRegistry; private final Ensemble ensemble; public EnsemblePlayer(Ensemble ensemble, Set<Actor> actors) { this.ensemble = ensemble; EnsembleRecording recording = ensemble.getRecording(); // We reverse the stack playerRecording = new EnsembleRecording(); for (int i = recording.size() - 1; i >= 0; i--) { this.playerRecording.push(recording.elementAt(i)); } // We register the actor this.globalRegistry = new ConcurrentHashMap<String, Object>(); for (Actor actor : actors) { this.globalRegistry.put(actor.role.getName(), actor.instance); } } public void run() { // Execution context // Stack<Object> localActorStack = new Stack<Object>(); int operationId = -1; EnsembleRecordItem pop = null; while (!playerRecording.empty()) { operationId++; System.out.println("-------------------------------- "); System.out.println("OperationId " + operationId); pop = playerRecording.pop(); Method m = pop.method; Object item = null; Object actorInstance = null; if (pop.roleName != null) { actorInstance = globalRegistry.get(pop.roleName); } if (actorInstance == null) { // we look in the local stack actorInstance = localActorStack.pop(); if (actorInstance == null) { throw new IllegalStateException("local stack should not be empty"); // or it would mean we handle static call in the } } // COnstruct arguments either from local stack either from constant Object[] localArgs = new Object[pop.arguments.length]; for (int i = localArgs.length - 1; i >= 0; i--) { Object object = pop.arguments[i]; if (object == null) { localArgs[i] = localActorStack.pop(); } else { localArgs[i] = treat(object); } } // item = invokeWithoutException(m, actorInstance, localArgs); if (!(pop.method.getReturnType().equals(Void.TYPE) || pop.method.getReturnType().equals(Void.class))) { localActorStack.push(item); } } } private Object treat(Object object) { Object o = object; if ( object.equals( Ensemble.NULL) || object.equals( Ensemble.NULL.toString())) { o = null; } return o; } private Object invokeWithoutException(Method m, Object self, Object... args) { Object o = null; try { o = m.invoke(self, args); } catch (IllegalArgumentException e) { System.err.println("> " + m); for (int i = 0; i < args.length; i++) { System.err.println("> " + args[i]); } e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return o; } }