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.ArrayList;
6   import java.util.Collection;
7   import java.util.LinkedList;
8   import java.util.List;
9   
10  import nl.tudelft.goal.EIS2Java.annotation.AsPercept;
11  import nl.tudelft.goal.EIS2Java.translation.Filter;
12  import nl.tudelft.goal.EIS2Java.util.EIS2JavaUtil;
13  import eis.exceptions.EntityException;
14  import eis.exceptions.PerceiveException;
15  import eis.iilang.Percept;
16  
17  public final class SynchronizedPerceptHandler extends AbstractPerceptHandler {
18  
19  	/** Collection of methods on the entity */
20  	protected final Collection<Method> perceptMethods;
21  	protected final AsynchronousEntity entity;
22  
23  	public SynchronizedPerceptHandler(AsynchronousEntity entity) throws EntityException {
24  		super(entity);
25  		this.entity = entity;
26  		this.perceptMethods = EIS2JavaUtil.processPerceptAnnotations(entity.getClass()).values();
27  	}
28  
29  	@Override
30  	public final LinkedList<Percept> getAllPercepts() throws PerceiveException {
31  
32  		LinkedList<Percept> percepts = new LinkedList<Percept>();
33  
34  		try {
35  			entity.acquire();
36  			try {
37  				for (Method method : perceptMethods) {
38  
39  					percepts.addAll(getPercepts(method));
40  				}
41  			} finally {
42  				entity.release();
43  			}
44  		} catch (InterruptedException e) {
45  			throw new PerceiveException("Unable to perceive any percepts. Could not aquire entity.", e);
46  		}
47  
48  		return percepts;
49  	}
50  
51  	/**
52  	 * Creates new percepts by calling the given method on the entity.
53  	 * 
54  	 * @param entity
55  	 *            the entity to get the percept from.
56  	 * @param method
57  	 *            the method to invoke on the entity which must be annotated
58  	 *            with {@link AsPercept}.
59  	 * @return The percepts that were generated by invoking the method on the
60  	 *         entity.
61  	 * @throws PerceiveException
62  	 *             If the percepts couldn't be retrieved.
63  	 */
64  	private List<Percept> getPercepts(Method method) throws PerceiveException {
65  
66  		// list of new objects for the percepts
67  		List<Object> perceptObjects = new ArrayList<Object>();
68  
69  		// Optimization, don't call methods for once percepts if they have been
70  		// called before.
71  		AsPercept annotation = method.getAnnotation(AsPercept.class);
72  		Filter.Type filter = annotation.filter();
73  		if (filter != Filter.Type.ONCE || previousPercepts.get(method) == null) {
74  			perceptObjects = getPerceptObjects(method);
75  		}
76  
77  		List<Percept> percepts = translatePercepts(method, perceptObjects);
78  		return percepts;
79  	}
80  
81  	/**
82  	 * Get the percept objects for given percept name, using method. CHECK why
83  	 * use all these params, we can get name from the method, right?
84  	 * 
85  	 * @param method
86  	 * @param entity
87  	 * @param perceptName
88  	 * @return
89  	 * @throws PerceiveException
90  	 */
91  	private List<Object> getPerceptObjects(Method method) throws PerceiveException {
92  
93  		AsPercept annotation = method.getAnnotation(AsPercept.class);
94  		String perceptName = annotation.name();
95  
96  		Object returnValue;
97  		try {
98  			returnValue = method.invoke(entity);
99  		} catch (IllegalArgumentException e) {
100 			throw new PerceiveException("Unable to perceive " + perceptName, e);
101 		} catch (IllegalAccessException e) {
102 			throw new PerceiveException("Unable to perceive " + perceptName, e);
103 		} catch (InvocationTargetException e) {
104 			throw new PerceiveException("Unable to perceive " + perceptName, e);
105 		}
106 
107 		return unpackPerceptObject(method, returnValue);
108 	}
109 
110 }