View Javadoc

1   /*
2    * Copyright © 2012 Eirik Bjornset.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package net.grinderscript.dotnet.scriptengine;
18  
19  import grinderscript.net.core.IGrinderScriptEngine;
20  import grinderscript.net.core.IGrinderContext;
21  import grinderscript.net.core.IGrinderWorker;
22  import grinderscript.net.core.framework.ScriptEngineBridgeFactory;
23  
24  import java.io.File;
25  import java.io.IOException;
26  import java.util.Properties;
27  
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import net.grinder.common.GrinderProperties;
32  import net.grinder.engine.common.EngineException;
33  import net.grinder.engine.common.ScriptLocation;
34  import net.grinder.script.Grinder;
35  import net.grinder.script.Grinder.ScriptContext;
36  import net.grinder.scriptengine.ScriptEngineService.ScriptEngine;
37  import net.grinder.scriptengine.ScriptEngineService.WorkerRunnable;
38  import net.sf.jni4net.Bridge;
39  
40  /**
41   * .Net script engine.
42   * 
43   * @author Eirik Bjornset
44   */
45  public class DotNetScriptEngine implements ScriptEngine {
46  
47  	private final Logger logger = LoggerFactory
48  			.getLogger(DotNetScriptEngine.class);
49  
50  	private final GrinderProperties properties;
51  	private final IGrinderContext context;
52  	private IGrinderScriptEngine underlying;
53  
54  	public DotNetScriptEngine(GrinderProperties properties,
55  			ScriptLocation script) {
56  		this(Grinder.grinder, properties, script);
57  	}
58  
59  	public DotNetScriptEngine(ScriptContext scriptContext,
60  			GrinderProperties properties, ScriptLocation script) {
61  		logger.trace(
62  				"ctor: Enter, scriptContext = {}, properties =  {}, script = {}",
63  				new Object[] { scriptContext, properties, script });
64  		this.properties = properties;
65  		context = new DotNetContextBridge(scriptContext, properties,
66  				script);
67  		logger.trace("ctor: Exit");
68  	}
69  
70  	public void initialize() throws DotNetScriptExecutionException, IOException {
71  		logger.trace("initialize: Enter");
72  		Bridge.setVerbose(properties.getBoolean(
73  				DotNetUtils.getPropertyName("bridgeVerbose"), false));
74  		Bridge.setDebug(properties.getBoolean(
75  				DotNetUtils.getPropertyName("bridgeDebug"), false));
76  		Properties jn4Properties = DotNetUtils.getPropertiesFromResources();
77  		logger.trace("initialize: jn4Properties = {}", jn4Properties);
78  		String j4nLocation = getJ4nLocationFromPropertiesOrCodeLocation(
79  				properties, jn4Properties);
80  		logger.trace("initialize: j4nLocation = {}", j4nLocation);
81  		String scriptAssemblyName = DotNetUtils.getProperty(jn4Properties,
82  				DotNetUtils.SCRIPT_ASSEMBLY_PROPERTY_SUFFIX);
83  		logger.trace("initialize: scriptAssemblyName = {}", scriptAssemblyName);
84  		String scriptAssemblyCanonicalPath = DotNetUtils
85  				.getCanonicalLocationFilePath(j4nLocation, scriptAssemblyName);
86  		logger.trace("initialize: scriptAssemblyCanonicalPath = {}",
87  				scriptAssemblyCanonicalPath);
88  		String j4nAssemblyName = DotNetUtils.getProperty(jn4Properties,
89  				DotNetUtils.J4N_ASSEMBLY_PROPERTY_SUFFIX);
90  		logger.trace("initialize: j4nAssemblyName = {}", j4nAssemblyName);
91  		String j4nAssemblyCanonicalPath = DotNetUtils
92  				.getCanonicalLocationFilePath(j4nLocation, j4nAssemblyName);
93  		logger.trace("initialize: j4nAssemblyCanonicalPath = {}",
94  				j4nAssemblyCanonicalPath);
95  		Bridge.init(new File(j4nLocation));
96  		Bridge.LoadAndRegisterAssemblyFrom(new File(scriptAssemblyCanonicalPath));
97  		Bridge.LoadAndRegisterAssemblyFrom(new File(j4nAssemblyCanonicalPath));
98  		initialize(ScriptEngineBridgeFactory.CreateBridge(context));
99  		logger.trace("initialize: Exit");
100 	}
101 
102 	@Override
103 	public WorkerRunnable createWorkerRunnable() throws EngineException {
104 		logger.trace("createWorkerRunnable: Enter");
105 		WorkerRunnable result = createWorkerRunnable(null);
106 		logger.trace("createWorkerRunnable: Exit");
107 		return result;
108 	}
109 
110 	@Override
111 	public WorkerRunnable createWorkerRunnable(Object testRunner)
112 			throws EngineException {
113 		logger.trace("createWorkerRunnable: Enter, testRunner = {}", testRunner);
114 		IGrinderWorker worker = underlying.CreateWorkerRunnable();
115 		logger.trace("createWorkerRunnable: Exit");
116 		return new DotNetWorkerRunnable(worker);
117 	}
118 
119 	@Override
120 	public String getDescription() {
121 		return "GrinderScript.Net Script Engine";
122 	}
123 
124 	@Override
125 	public void shutdown() throws EngineException {
126 		logger.trace("shutdown: Enter");
127 		if (underlying != null) {
128 			try {
129 				underlying.Shutdown();
130 			} finally {
131 				underlying = null;
132 			}
133 		}
134 		logger.trace("shutdown: Exit");
135 	}
136 	
137 	void initialize(IGrinderScriptEngine scriptEngine) {
138 		logger.trace("initialize: Enter, scriptEngine = {}", scriptEngine);
139 		scriptEngine.Initialize();
140 		this.underlying = scriptEngine;
141 		logger.trace("initialize: Exit");
142 	}
143 
144 	String getJ4nLocationFromPropertiesOrCodeLocation(
145 			GrinderProperties grinderProperties, Properties j4nProperties)
146 			throws DotNetScriptExecutionException, IOException {
147 		logger.trace(
148 				"getJ4nLocationFromPropertiesOrCodeLocation: Enter, filePropertySuffix = {}, grinderProperties = {}, j4nProperties = {}",
149 				grinderProperties, j4nProperties);
150 		String j4nLocation;
151 		String j4nLocationPropertyKey = DotNetUtils
152 				.getPropertyName(DotNetUtils.J4N_LOCATION_PROPERTY_SUFFIX);
153 		if (grinderProperties.containsKey(j4nLocationPropertyKey)) {
154 			j4nLocation = grinderProperties.getProperty(j4nLocationPropertyKey);
155 			logger.trace(
156 					"getJ4nLocationFromPropertiesOrCodeLocation: Found j4nLocation property \"{}\" in grinderProperties",
157 					j4nLocationPropertyKey);
158 		} else if (j4nProperties.containsKey(j4nLocationPropertyKey)) {
159 			j4nLocation = j4nProperties.getProperty(j4nLocationPropertyKey);
160 			logger.trace(
161 					"getJ4nLocationFromPropertiesOrCodeLocation: Found j4nLocation property \"{}\" in j4nProperties",
162 					j4nLocationPropertyKey);
163 		} else {
164 			j4nLocation = DotNetUtils.getDirectoryFromJ4nCodeLocation();
165 			logger.trace("getJ4nLocationFromPropertiesOrCodeLocation: Using j4n code base as j4nLocation");
166 		}
167 		logger.trace(
168 				"getJ4nLocationFromPropertiesOrCodeLocation: Exit, j4nLocation = \"{}\"",
169 				j4nLocation);
170 		return j4nLocation;
171 	}
172 	
173 	GrinderProperties getProperties() {
174 		return properties;
175 	}
176 	
177 	IGrinderContext getContext()
178 	{
179 		return context;
180 	}
181 	
182 	IGrinderScriptEngine getUnderlying() {
183 		return underlying;
184 	}
185 	
186 }