/** * */ package org.opentrafficsim.water; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; import org.djutils.reflection.ClassUtil; import nl.tudelft.simulation.dsol.SimRuntimeException; /** *

* Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

*

* Based on software from the IDVV project, which is Copyright (c) 2013 Rijkswaterstaat - Dienst Water, Verkeer en Leefomgeving * and licensed without restrictions to Delft University of Technology, including the right to sub-license sources and derived * products to third parties. *

* $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $, * initial version Nov 6, 2016
* @author Alexander Verbraeck */ public class SchedulableMethod implements Serializable { /** */ private static final long serialVersionUID = 1L; /** target reflects the target on which a state change is scheduled. */ @SuppressWarnings("checkstyle:visibilitymodifier") protected Object target = null; /** method is the method which embodies the state change. */ @SuppressWarnings("checkstyle:visibilitymodifier") protected String method = null; /** args are the arguments which are used to invoke the method with. */ @SuppressWarnings("checkstyle:visibilitymodifier") protected Object[] args = null; /** cache. */ private static Map cacheMethods = new LinkedHashMap(); /** * The constructor of the schedulable method stores the object and method to invoke with its arguments. * @param target Object; reflects the object on which the method must be invoked. * @param method String; reflects the method to invoke * @param args Object[]; reflects the argumenst the method to invoke with */ public SchedulableMethod(final Object target, final String method, final Object[] args) { if (target == null || method == null) { throw new IllegalArgumentException("target or method==null"); } this.target = target; this.method = method; this.args = args; } /** * Executes the method. Method <init> means the constructor. */ public final synchronized void execute() { try { if (this.method.equals("")) { if (!(this.target instanceof Class)) { throw new SimRuntimeException("Invoking a constructor implies that target should be instance of Class"); } Constructor constructor = ClassUtil.resolveConstructor((Class) this.target, this.args); constructor.setAccessible(true); constructor.newInstance(this.args); } else { String key = this.target.getClass().getName() + "_" + this.method; Method tm = cacheMethods.get(key); if (tm == null) { tm = ClassUtil.resolveMethod(this.target, this.method, this.args); cacheMethods.put(key, tm); } tm.setAccessible(true); tm.invoke(this.target, this.args); } } catch (Exception exception) { exception.printStackTrace(); } } /** * @return Returns the args. */ public final Object[] getArgs() { return this.args; } /** * @return Returns the method. */ public final String getMethod() { return this.method; } /** * @return Returns the target. */ public final Object getTarget() { return this.target; } /** {@inheritDoc} */ @Override public final String toString() { return "SchedulableMethod[target=" + this.target + "; method=" + this.method + "; args=" + this.args + "]"; } }