View Javadoc
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 org.djutils.reflection.ClassUtil;
13  
14  import nl.tudelft.simulation.dsol.SimRuntimeException;
15  
16  /**
17   * <p>
18   * Copyright (c) 2013-2019 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 HashMap<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 &lt;init&gt; 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 }