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