View Javadoc

1   package nl.tudelft.goal.EIS2Java.handlers;
2   
3   import java.lang.reflect.InvocationTargetException;
4   import java.lang.reflect.Method;
5   import java.util.HashMap;
6   import java.util.LinkedList;
7   import java.util.Map;
8   
9   import nl.tudelft.goal.EIS2Java.exception.TranslationException;
10  import nl.tudelft.goal.EIS2Java.translation.Translator;
11  import nl.tudelft.goal.EIS2Java.util.EIS2JavaUtil;
12  
13  import eis.exceptions.ActException;
14  import eis.exceptions.EntityException;
15  import eis.iilang.Action;
16  import eis.iilang.Parameter;
17  import eis.iilang.Percept;
18  
19  public class SynchronizedActionHandler extends ActionHandler {
20  
21  	protected final Map<String, Method> actionMethods;
22  	protected final AsynchronousEntity entity;
23  
24  	public SynchronizedActionHandler(AsynchronousEntity entity) throws EntityException {
25  		this.entity = entity;
26  		this.actionMethods = EIS2JavaUtil.processActionAnnotations(entity.getClass());
27  	}
28  
29  	@Override
30  	public final boolean isSupportedByEntity(Action action) {
31  		String actionName = EIS2JavaUtil.getNameOfAction(action);
32  		return actionMethods.get(actionName) != null;
33  	}
34  
35  	@Override
36  	public final Percept performAction(Action action) throws ActException {
37  		String actionName = EIS2JavaUtil.getNameOfAction(action);
38  		Method actionMethod = actionMethods.get(actionName);
39  		if (actionMethod == null) {
40  			throw new ActException(ActException.FAILURE, "Entity does not support action: " + action);
41  		}
42  
43  		// workaround/fix for an EIS issue. #1986.
44  		try {
45  			return performAction(entity, actionMethod, action.getName(), action.getParameters());
46  		} catch (Exception e) {
47  			if (e instanceof ActException) {
48  				throw (ActException) e;
49  			}
50  			throw new ActException(ActException.FAILURE, "execution of action " + action + "failed", e);
51  		}
52  	}
53  
54  	/**
55  	 * Performs the action method on the given method using the parameters. The
56  	 * returned {@link Percept} will have the same name as the action.
57  	 * 
58  	 * @param entity
59  	 *            The entity to perform the method on.
60  	 * @param method
61  	 *            The method to invoke on the entity.
62  	 * @param actionName
63  	 *            The name of the action that is being performed.
64  	 * @param parameters
65  	 *            The parameters to the method (before translation).
66  	 * @return The percept generated by the action.
67  	 * @throws ActException
68  	 *             if the action can not be performed for any reason.
69  	 */
70  	private Percept performAction(AsynchronousEntity entity, Method method, String actionName,
71  			LinkedList<Parameter> parameters) throws ActException {
72  		Translator translator = Translator.getInstance();
73  
74  		Class<?>[] parameterTypes = method.getParameterTypes();
75  
76  		Object[] arguments = new Object[parameters.size()];
77  		// Doing it the hard way because LinkedList.get(index) sucks!
78  		int i = 0;
79  		for (Parameter parameter : parameters) {
80  			try {
81  				arguments[i] = translator.translate2Java(parameter, parameterTypes[i]);
82  			} catch (TranslationException e) {
83  				throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
84  						+ " failed to be translated", e);
85  			}
86  			i++;
87  		}
88  
89  		Object returnValue;
90  		try {
91  			entity.acquire();
92  			try {
93  				returnValue = method.invoke(entity, arguments);
94  			} finally {
95  				entity.release();
96  			}
97  
98  		} catch (IllegalArgumentException e) {
99  			throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
100 					+ " failed to execute", e);
101 		} catch (IllegalAccessException e) {
102 			throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
103 					+ " failed to execute", e);
104 		} catch (InvocationTargetException e) {
105 			throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
106 					+ " failed to execute", e);
107 		} catch (InterruptedException e) {
108 			throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
109 					+ " failed to execute. Interupted while aquiring the entity.", e);
110 		}
111 		if (returnValue == null) {
112 			return null;
113 		} else {
114 			try {
115 				return new Percept(actionName, translator.translate2Parameter(returnValue));
116 			} catch (TranslationException e) {
117 				throw new ActException(ActException.FAILURE, "Action " + actionName + " with parameters " + parameters
118 						+ " failed to return a proper failue", e);
119 			}
120 		}
121 	}
122 
123 }