package eis.eis2java.handlers; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import eis.eis2java.annotation.AsPercept; import eis.eis2java.translation.Filter; import eis.eis2java.util.EIS2JavaUtil; import eis.exceptions.EntityException; import eis.exceptions.PerceiveException; import eis.iilang.Percept; /** * Default {@link PerceptHandler} for EIS2Java. When called the * DefaultPercepthandler will call all percept methods on the agent and return * and translate their results. * * @author mpkorstanje * */ public final class DefaultPerceptHandler extends AbstractPerceptHandler { /** Collection of methods on the entity (that were annotated with @Percept) */ protected final Collection<Method> perceptMethods; public DefaultPerceptHandler(Object entity) throws EntityException { super(entity); this.perceptMethods = EIS2JavaUtil.processPerceptAnnotations(entity .getClass()); } /* * (non-Javadoc) * * @see * nl.tudelft.goal.EIS2Java.environment.PerceptHandler#getAllPercepts(java * .lang.Object) */ @Override public final LinkedList<Percept> getAllPercepts() throws PerceiveException { LinkedList<Percept> percepts = new LinkedList<Percept>(); for (Method method : perceptMethods) { percepts.addAll(getPercepts(method)); } return percepts; } /** * Creates new percepts by calling the given method on the entity. * * @param entity * the entity to get the percept from. * @param method * the method to invoke on the entity which must be annotated * with {@link AsPercept}. * @return The percepts that were generated by invoking the method on the * entity. * @throws PerceiveException * If the percepts couldn't be retrieved. */ private List<Percept> getPercepts(Method method) throws PerceiveException { // list of new objects for the percepts List<Object> perceptObjects = new ArrayList<Object>(); // Optimization, don't call methods for once percepts if they have been // called before. AsPercept annotation = method.getAnnotation(AsPercept.class); Filter.Type filter = annotation.filter(); if (filter != Filter.Type.ONCE || previousPercepts.get(method) == null) { perceptObjects = getPerceptObjects(method); } List<Percept> percepts = translatePercepts(method, perceptObjects); return percepts; } /** * Get the percept objects for given percept name, using method. May return * an empty list. * * @param method * @param entity * @param perceptName * @return percept objects for given percept name, using method. May return * an empty list * @throws PerceiveException */ private List<Object> getPerceptObjects(Method method) throws PerceiveException { AsPercept annotation = method.getAnnotation(AsPercept.class); String perceptName = annotation.name(); Object returnValue; try { returnValue = method.invoke(entity); } catch (IllegalArgumentException e) { throw new PerceiveException("Unable to perceive " + perceptName, e); } catch (IllegalAccessException e) { throw new PerceiveException("Unable to perceive " + perceptName, e); } catch (InvocationTargetException e) { throw new PerceiveException("Unable to perceive " + perceptName, e); } return unpackPerceptObject(method, returnValue); } }