1 /**
2 *
3 */
4 package org.opentrafficsim.water;
5
6 import java.io.Serializable;
7 import java.lang.reflect.Constructor;
8 import java.lang.reflect.Method;
9 import java.util.LinkedHashMap;
10 import java.util.Map;
11
12 import org.djutils.reflection.ClassUtil;
13
14 import nl.tudelft.simulation.dsol.SimRuntimeException;
15
16 /**
17 * <p>
18 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
19 * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
20 * </p>
21 * <p>
22 * Based on software from the IDVV project, which is Copyright (c) 2013 Rijkswaterstaat - Dienst Water, Verkeer en Leefomgeving
23 * and licensed without restrictions to Delft University of Technology, including the right to sub-license sources and derived
24 * products to third parties.
25 * </p>
26 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
27 * initial version Nov 6, 2016 <br>
28 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
29 */
30 public class SchedulableMethod implements Serializable
31 {
32 /** */
33 private static final long serialVersionUID = 1L;
34
35 /** target reflects the target on which a state change is scheduled. */
36 @SuppressWarnings("checkstyle:visibilitymodifier")
37 protected Object target = null;
38
39 /** method is the method which embodies the state change. */
40 @SuppressWarnings("checkstyle:visibilitymodifier")
41 protected String method = null;
42
43 /** args are the arguments which are used to invoke the method with. */
44 @SuppressWarnings("checkstyle:visibilitymodifier")
45 protected Object[] args = null;
46
47 /** cache. */
48 private static Map<String, Method> cacheMethods = new LinkedHashMap<String, Method>();
49
50 /**
51 * The constructor of the schedulable method stores the object and method to invoke with its arguments.
52 * @param target Object; reflects the object on which the method must be invoked.
53 * @param method String; reflects the method to invoke
54 * @param args Object[]; reflects the argumenst the method to invoke with
55 */
56 public SchedulableMethod(final Object target, final String method, final Object[] args)
57 {
58 if (target == null || method == null)
59 {
60 throw new IllegalArgumentException("target or method==null");
61 }
62 this.target = target;
63 this.method = method;
64 this.args = args;
65 }
66
67 /**
68 * Executes the method. Method <init> means the constructor.
69 */
70 public final synchronized void execute()
71 {
72 try
73 {
74 if (this.method.equals("<init>"))
75 {
76 if (!(this.target instanceof Class))
77 {
78 throw new SimRuntimeException("Invoking a constructor implies that target should be instance of Class");
79 }
80 Constructor<?> constructor = ClassUtil.resolveConstructor((Class<?>) this.target, this.args);
81 constructor.setAccessible(true);
82 constructor.newInstance(this.args);
83 }
84 else
85 {
86 String key = this.target.getClass().getName() + "_" + this.method;
87 Method tm = cacheMethods.get(key);
88 if (tm == null)
89 {
90 tm = ClassUtil.resolveMethod(this.target, this.method, this.args);
91 cacheMethods.put(key, tm);
92 }
93 tm.setAccessible(true);
94 tm.invoke(this.target, this.args);
95 }
96 }
97 catch (Exception exception)
98 {
99 exception.printStackTrace();
100 }
101 }
102
103 /**
104 * @return Returns the args.
105 */
106 public final Object[] getArgs()
107 {
108 return this.args;
109 }
110
111 /**
112 * @return Returns the method.
113 */
114 public final String getMethod()
115 {
116 return this.method;
117 }
118
119 /**
120 * @return Returns the target.
121 */
122 public final Object getTarget()
123 {
124 return this.target;
125 }
126
127 /** {@inheritDoc} */
128 @Override
129 public final String toString()
130 {
131 return "SchedulableMethod[target=" + this.target + "; method=" + this.method + "; args=" + this.args + "]";
132 }
133
134 }