View Javadoc

1   // Copyright (C) 2011 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.scriptengine;
23  
24  import java.util.List;
25  
26  import net.grinder.engine.common.EngineException;
27  import net.grinder.engine.common.ScriptLocation;
28  
29  /**
30   * Service interface that script engines should implement.
31   *
32   * <p>
33   * The Grinder discovers script engine implementations from the {@code
34   * META-INF/net.grinder.scriptengines} resource files. Each engine should
35   * register its class name as a line in such a resource file. The order of the
36   * search engines is important, since it determines priority. The engines are
37   * ordered first by the class path search order used to load the resource files,
38   * and then the order of lines in the resource files. Earlier engines have
39   * higher priority.
40   * </p>
41   *
42   * <p>
43   * Each script engine is injected with framework services using PicoContainer.
44   * The use of PicoContainer should be transparent; implementations simply need
45   * to declare the services they require as constructor parameters.
46   * </p>
47   *
48   * <p>
49   * Available services include:
50   * </p>
51   *
52   * <ul>
53   * <li><code>net.grinder.common.Logger</code></li>
54   * <li><code>net.grinder.common.GrinderProperties</code></li>
55   * <li><code>net.grinder.script.ScriptContext</code></li>
56   * <li><code>net.grinder.scriptengine.DCRContext</code></li>
57   * </ul>
58   *
59   * <p>
60   * A {@code DCRContext} will be provided only if DCR is available. Engines that
61   * use DCR should have two constructors, one of them requiring a {@code
62   * DCRContext}, and one of them not. The latter constructor will be used if DCR
63   * is unavailable.
64   * </p>
65   *
66   * @author Philip Aston
67   */
68  public interface ScriptEngineService {
69  
70    /**
71     * All resources with this name are loaded to discover implementations.
72     */
73    String RESOURCE_NAME = "META-INF/net.grinder.scriptengine";
74  
75    /**
76     * If the script engine service can handle the given script, it should return
77     * a suitable implementation.
78     *
79     * <p>
80     * Implementations typically will execute the script and perform any
81     * process level initialisation.
82     * </p>
83     *
84     * @param script
85     *          The script.
86     * @return The script engine, or {@code null}.
87     * @throws EngineException
88     *           If an implementation could not be created.
89     */
90    ScriptEngine createScriptEngine(ScriptLocation script) throws EngineException;
91  
92    /**
93     * Initialises script engine instrumentation.
94     *
95     * <p>
96     * Each script engine can provide instrumenters, irrespective of the engine
97     * used to execute the script. The instrumenters provided by each engine are
98     * consulted according to service registration order in the META-INF file.
99     * </p>
100    *
101    * @return Additional instrumenters to use. Engines that do not provide
102    *         instrumentation should return an empty list.
103    * @throws EngineException
104    *           If a problem occurred creating instrumenters.
105    */
106   List<? extends Instrumenter> createInstrumenters() throws EngineException;
107 
108   /**
109    * Handler for a particular type of script.
110    */
111   interface ScriptEngine {
112 
113     /**
114      * Create a {@link WorkerRunnable} that will be used to run the work
115      * for one worker thread. The {@link WorkerRunnable} will forward to
116      * a new instance of the script's {@code TestRunner} class.
117      *
118      * @return The runnable.
119      * @throws EngineException If the runnable could not be created.
120      */
121     WorkerRunnable createWorkerRunnable() throws EngineException;
122 
123     /**
124      * Create a {@link WorkerRunnable} that will be used to run the work
125      * for one worker thread. The {@link WorkerRunnable} will forward to
126      * a the supplied {@code TestRunner}.
127      *
128      * @param testRunner An existing script instance that is callable.
129      * @return The runnable.
130      * @throws EngineException If the runnable could not be created.
131      */
132     WorkerRunnable createWorkerRunnable(Object testRunner)
133       throws EngineException;
134 
135     /**
136      * Shut down the engine.
137      *
138      * @throws EngineException If the engine could not be shut down.
139      */
140     void shutdown() throws EngineException;
141 
142     /**
143      * Returns a description of the script engine for the log.
144      *
145      * @return The description.
146      */
147     String getDescription();
148   }
149 
150   /**
151    * Interface to the runnable script object for a particular worker thread.
152    */
153   interface WorkerRunnable {
154     void run() throws ScriptExecutionException;
155 
156     void shutdown() throws ScriptExecutionException;
157   }
158 }