##### Coverage Report - org.jbehave.ant.AbstractEmbedderTask

Classes in this File | Line Coverage | Branch Coverage | Complexity
AbstractEmbedderTask |
92% | 109/118
72% | 13/18
| 1.2878787878787878;1.288
AbstractEmbedderTask$AntEmbedderMonitor |
40% | 28/69
12% | 1/8
| 1.2878787878787878;1.288

1 |  |
     package org.jbehave.ant;
2 |  |
3 |  |
     import java.io.File;
4 |  |
     import java.io.IOException;
5 |  |
     import java.net.MalformedURLException;
6 |  |
     import java.net.URL;
7 |  |
     import java.util.ArrayList;
8 |  |
     import java.util.List;
9 |  |
     import java.util.Properties;
10 |  |
     import java.util.concurrent.ExecutorService;
11 |  |
12 |  |
     import org.apache.tools.ant.Task;
13 |  |
     import org.apache.tools.ant.filters.StringInputStream;
14 |  |
     import org.jbehave.core.ConfigurableEmbedder;
15 |  |
     import org.jbehave.core.InjectableEmbedder;
16 |  |
     import org.jbehave.core.embedder.Embedder;
17 |  |
     import org.jbehave.core.embedder.EmbedderClassLoader;
18 |  |
     import org.jbehave.core.embedder.EmbedderControls;
19 |  |
     import org.jbehave.core.embedder.EmbedderMonitor;
20 |  |
     import org.jbehave.core.embedder.MetaFilter;
21 |  |
     import org.jbehave.core.embedder.NullEmbedderMonitor;
22 |  |
     import org.jbehave.core.embedder.UnmodifiableEmbedderControls;
23 |  |
     import org.jbehave.core.embedder.executors.ExecutorServiceFactory;
24 |  |
     import org.jbehave.core.failures.BatchFailures;
25 |  |
     import org.jbehave.core.io.StoryFinder;
26 |  |
     import org.jbehave.core.junit.AnnotatedEmbedderRunner;
27 |  |
     import org.jbehave.core.model.Meta;
28 |  |
     import org.jbehave.core.model.Story;
29 |  |
     import org.jbehave.core.model.StoryDuration;
30 |  |
     import org.jbehave.core.model.StoryMaps;
31 |  |
     import org.jbehave.core.reporters.ReportsCount;
32 |  |
33 |  |
     import static java.util.Arrays.asList;
34 |  |
     import static org.apache.tools.ant.Project.MSG_DEBUG;
35 |  |
     import static org.apache.tools.ant.Project.MSG_INFO;
36 |  |
     import static org.apache.tools.ant.Project.MSG_WARN;
37 |  |
38 |  |
     /**
39 |  |
      * Abstract task that holds all the configuration parameters to specify and load
40 |  |
      * stories.
41 |  |
      *
42 |  |
      * @author Mauro Talevi
43 |  |
      */
44 | 16 |
     public abstract class AbstractEmbedderTask extends Task {
45 |  |
46 |  |
         private static final String TEST_SCOPE = "test";
47 |  |
48 | 16 |
         private String sourceDirectory = "src/main/java";
49 |  |
50 | 16 |
         private String testSourceDirectory = "src/test/java";
51 |  |
52 | 16 |
         private String outputDirectory = "target/classes";
53 |  |
54 | 16 |
         private String testOutputDirectory = "target/test-classes";
55 |  |
56 |  |
         /**
57 |  |
          * The scope of the source, either "compile" or "test"
58 |  |
          */
59 | 16 |
         private String scope = "compile";
60 |  |
61 |  |
         /**
62 |  |
          * Include filters, relative to the root source directory determined by the
63 |  |
          * scope
64 |  |
          */
65 | 16 |
         private List<String> includes = new ArrayList<String>();
66 |  |
67 |  |
         /**
68 |  |
          * Exclude filters, relative to the root source directory determined by the
69 |  |
          * scope
70 |  |
          */
71 | 16 |
         private List<String> excludes = new ArrayList<String>();
72 |  |
73 |  |
         /**
74 |  |
          * The boolean flag to skip running stories
75 |  |
          */
76 | 16 |
         private boolean skip = false;
77 |  |
78 |  |
         /**
79 |  |
          * The boolean flag to ignore failure in stories
80 |  |
          */
81 | 16 |
         private boolean ignoreFailureInStories = false;
82 |  |
83 |  |
         /**
84 |  |
          * The boolean flag to ignore failure in view
85 |  |
          */
86 | 16 |
         private boolean ignoreFailureInView = false;
87 |  |
88 |  |
         /**
89 |  |
          * The boolean flag to generate view after stories
90 |  |
          */
91 | 16 |
         private boolean generateViewAfterStories = true;
92 |  |
93 |  |
         /**
94 |  |
          * The boolean flag to run in batch mode
95 |  |
          */
96 | 16 |
         private boolean batch = false;
97 |  |
98 |  |
         /**
99 |  |
          * The boolean flag to output failures in verbose mode
100 |  |
          */
101 | 16 |
         private boolean verboseFailures = false;
102 |  |
103 |  |
         /**
104 |  |
          * The boolean flag to output filtering in verbose mode
105 |  |
          */
106 | 16 |
         private boolean verboseFiltering = false;
107 |  |
108 |  |
         /**
109 |  |
          * The story timeout in secs
110 |  |
          */
111 | 16 |
         long storyTimeoutInSecs = 300;
112 |  |
113 |  |
         /**
114 |  |
          * The number of threads
115 |  |
          */
116 | 16 |
         private int threads = 1;
117 |  |
118 |  |
         /**
119 |  |
          * The embedder to run the stories
120 |  |
          */
121 | 16 |
         private String embedderClass = Embedder.class.getName();
122 |  |
123 |  |
         /**
124 |  |
          * The implementation class of the {@link ExecutorServiceFactory}
125 |  |
          */
126 |  |
         private String executorsClass;
127 |  |
128 |  |
         /**
129 |  |
          * The class that is injected to provide embedder to run the stories.
130 |  |
          */
131 |  |
         private String injectableEmbedderClass;
132 |  |
133 |  |
         /**
134 |  |
          * The annotated embedder runner class to run the stories
135 |  |
          *
136 |  |
          * @deprecated Obsolete
137 |  |
          */
138 | 16 |
         String annotatedEmbedderRunnerClass = AnnotatedEmbedderRunner.class.getName();
139 |  |
140 |  |
         /**
141 |  |
          * Used to find story paths and class names
142 |  |
          */
143 | 16 |
         private String storyFinderClass = StoryFinder.class.getName();
144 |  |
145 |  |
         /**
146 |  |
          * The meta filters
147 |  |
          */
148 | 16 |
         private List<String> metaFilters = asList();
149 |  |
150 |  |
         /**
151 |  |
          * The system properties
152 |  |
          */
153 | 16 |
         private Properties systemProperties = new Properties();
154 |  |
155 |  |
         /**
156 |  |
          * The classloader
157 |  |
          */
158 |  |
         private EmbedderClassLoader classLoader;
159 |  |
160 |  |
         /**
161 |  |
          * Determines if the scope of the source directory is "test"
162 |  |
          *
163 |  |
          * @return A boolean <code>true</code> if test scoped
164 |  |
          */
165 |  |
         boolean isTestScope() {
166 | 14 |
             return TEST_SCOPE.equals(scope);
167 |  |
         }
168 |  |
169 |  |
         String searchDirectory() {
170 | 6 |
             if (isTestScope()) {
171 | 1 |
                 return testSourceDirectory;
172 |  |
             }
173 | 5 |
             return sourceDirectory;
174 |  |
         }
175 |  |
176 |  |
         String outputDirectory() {
177 | 8 |
             if (isTestScope()) {
178 | 0 |
                 return testOutputDirectory;
179 |  |
             }
180 | 8 |
             return outputDirectory;
181 |  |
         }
182 |  |
183 |  |
         URL codeLocation() {
184 | 8 |
             String outputDirectory = outputDirectory();
185 |  |
             try {
186 | 8 |
                 return outputDirectory != null ? new File(outputDirectory).toURI().toURL() : null;
187 | 0 |
             } catch (MalformedURLException e) {
188 | 0 |
                 throw new IllegalArgumentException("Failed to create code location from " + outputDirectory, e);
189 |  |
             }
190 |  |
         }
191 |  |
192 |  |
         /**
193 |  |
          * Creates the EmbedderClassLoader with the classpath element of the
194 |  |
          * selected scope
195 |  |
          *
196 |  |
          * @return A EmbedderClassLoader
197 |  |
          */
198 |  |
         protected EmbedderClassLoader classLoader() {
199 | 8 |
             if (classLoader == null) {
200 | 8 |
                 classLoader = new EmbedderClassLoader(this.getClass().getClassLoader());
201 |  |
             }
202 | 8 |
             return classLoader;
203 |  |
         }
204 |  |
205 |  |
         protected EmbedderMonitor embedderMonitor() {
206 | 7 |
             return new AntEmbedderMonitor();
207 |  |
         }
208 |  |
209 |  |
         protected EmbedderControls embedderControls() {
210 | 7 |
             return new UnmodifiableEmbedderControls(new EmbedderControls().doBatch(batch).doSkip(skip)
211 |  |
                     .doGenerateViewAfterStories(generateViewAfterStories).doIgnoreFailureInStories(ignoreFailureInStories)
212 |  |
                     .doIgnoreFailureInView(ignoreFailureInView).doVerboseFailures(verboseFailures)
213 |  |
                     .doVerboseFiltering(verboseFiltering).useStoryTimeoutInSecs(storyTimeoutInSecs).useThreads(threads));
214 |  |
         }
215 |  |
216 |  |
         /**
217 |  |
          * Finds story paths, using the {@link #newStoryFinder()}, in the
218 |  |
          * {@link #searchDirectory()} given specified {@link #includes} and
219 |  |
          * {@link #excludes}.
220 |  |
          *
221 |  |
          * @return A List of story paths found
222 |  |
          */
223 |  |
         protected List<String> storyPaths() {
224 | 2 |
             log("Searching for story paths including " + includes + " and excluding " + excludes, MSG_DEBUG);
225 | 2 |
             List<String> storyPaths = newStoryFinder().findPaths(searchDirectory(), includes, excludes);
226 | 2 |
             log("Found story paths: " + storyPaths, MSG_INFO);
227 | 2 |
             return storyPaths;
228 |  |
         }
229 |  |
230 |  |
         /**
231 |  |
          * Finds class names, using the {@link #newStoryFinder()}, in the
232 |  |
          * {@link #searchDirectory()} given specified {@link #includes} and
233 |  |
          * {@link #excludes}.
234 |  |
          *
235 |  |
          * @return A List of class names found
236 |  |
          */
237 |  |
         protected List<String> classNames() {
238 | 3 |
             log("Searching for class names including " + includes + " and excluding " + excludes, MSG_DEBUG);
239 | 3 |
             List<String> classNames = newStoryFinder().findClassNames(searchDirectory(), includes, excludes);
240 | 3 |
             log("Found class names : " + classNames, MSG_INFO);
241 | 3 |
             return classNames;
242 |  |
         }
243 |  |
244 |  |
         /**
245 |  |
          * Creates an instance of StoryFinder, using the {@link #storyFinderClass}
246 |  |
          *
247 |  |
          * @return A StoryFinder
248 |  |
          */
249 |  |
         protected StoryFinder newStoryFinder() {
250 | 6 |
             return classLoader().newInstance(StoryFinder.class, storyFinderClass);
251 |  |
         }
252 |  |
253 |  |
         /**
254 |  |
          * Creates an instance of Embedder, either using
255 |  |
          * {@link #injectableEmbedderClass} (if set) or defaulting to
256 |  |
          * {@link #embedderClass}.
257 |  |
          *
258 |  |
          * @return An Embedder
259 |  |
          */
260 |  |
         protected Embedder newEmbedder() {
261 | 7 |
             Embedder embedder = null;
262 | 7 |
             EmbedderClassLoader classLoader = classLoader();
263 | 7 |
             if (injectableEmbedderClass != null) {
264 | 1 |
                 embedder = classLoader.newInstance(InjectableEmbedder.class, injectableEmbedderClass).injectedEmbedder();
265 |  |
             } else {
266 | 6 |
                 embedder = classLoader.newInstance(Embedder.class, embedderClass);
267 |  |
             }
268 |  |
269 | 7 |
             URL codeLocation = codeLocation();
270 | 7 |
             if (codeLocation != null) {
271 | 7 |
                 embedder.configuration().storyReporterBuilder().withCodeLocation(codeLocation);
272 |  |
             }
273 |  |
274 | 7 |
             embedder.useClassLoader(classLoader);
275 | 7 |
             embedder.useEmbedderControls(embedderControls());
276 | 7 |
             if (executorsClass != null) {
277 | 1 |
                 ExecutorServiceFactory executorServiceFactory = classLoader.newInstance(ExecutorServiceFactory.class,
278 |  |
                         executorsClass);
279 | 1 |
                 embedder.useExecutorService(executorServiceFactory.create(embedder.embedderControls()));
280 |  |
             }
281 | 7 |
             embedder.useEmbedderMonitor(embedderMonitor());
282 | 7 |
             if (!metaFilters.isEmpty()) {
283 | 0 |
                 embedder.useMetaFilters(metaFilters);
284 |  |
             }
285 | 7 |
             if (!systemProperties.isEmpty()) {
286 | 1 |
                 embedder.useSystemProperties(systemProperties);
287 |  |
             }
288 | 7 |
             return embedder;
289 |  |
         }
290 |  |
291 | 7 |
         protected class AntEmbedderMonitor extends NullEmbedderMonitor {
292 |  |
             public void batchFailed(BatchFailures failures) {
293 | 1 |
                 log("Failed to run batch " + failures, MSG_WARN);
294 | 1 |
             }
295 |  |
296 |  |
             public void beforeOrAfterStoriesFailed() {
297 | 0 |
                 log("Failed to run before or after stories steps", MSG_WARN);
298 | 0 |
             }
299 |  |
300 |  |
             public void embeddableFailed(String name, Throwable cause) {
301 | 1 |
                 log("Failed to run embeddable " + name, cause, MSG_WARN);
302 | 1 |
             }
303 |  |
304 |  |
             public void embeddableNotConfigurable(String name) {
305 | 0 |
                 log("Embeddable " + name + " must be an instance of " + ConfigurableEmbedder.class, MSG_WARN);
306 | 0 |
             }
307 |  |
308 |  |
             public void embeddablesSkipped(List<String> classNames) {
309 | 1 |
                 log("Skipped embeddables " + classNames, MSG_INFO);
310 | 1 |
             }
311 |  |
312 |  |
             public void metaNotAllowed(Meta meta, MetaFilter filter) {
313 | 0 |
                 log(meta + " excluded by filter '" + filter.asString() + "'", MSG_DEBUG);
314 | 0 |
             }
315 |  |
316 |  |
             public void runningEmbeddable(String name) {
317 | 1 |
                 log("Running embeddable " + name, MSG_INFO);
318 | 1 |
             }
319 |  |
320 |  |
             public void storyFailed(String path, Throwable cause) {
321 | 1 |
                 log("Failed to run story " + path, cause, MSG_WARN);
322 | 1 |
             }
323 |  |
324 |  |
             public void storiesSkipped(List<String> storyPaths) {
325 | 1 |
                 log("Skipped stories " + storyPaths, MSG_INFO);
326 | 1 |
             }
327 |  |
328 |  |
             public void storiesNotAllowed(List<Story> stories, MetaFilter filter, boolean verbose) {
329 | 0 |
                 StringBuffer sb = new StringBuffer();
330 | 0 |
                 sb.append(stories.size() + " stories excluded by filter: " + filter.asString() + "\n");
331 | 0 |
                 if (verbose) {
332 | 0 |
                     for (Story story : stories) {
333 | 0 |
                         sb.append(story.getPath()).append("\n");
334 |  |
                     }
335 |  |
                 }
336 | 0 |
                 log(sb.toString(), MSG_INFO);
337 | 0 |
             }
338 |  |
339 |  |
             public void runningStory(String path) {
340 | 1 |
                 log("Running story " + path, MSG_INFO);
341 | 1 |
             }
342 |  |
343 |  |
             public void runningWithAnnotatedEmbedderRunner(String className) {
344 | 0 |
                 log("Running with AnnotatedEmbedderRunner '" + className + "'", MSG_INFO);
345 | 0 |
             }
346 |  |
347 |  |
             public void annotatedInstanceNotOfType(Object annotatedInstance, Class<?> type) {
348 | 1 |
                 log("Annotated instance " + annotatedInstance + " not of type " + type, MSG_WARN);
349 | 1 |
             }
350 |  |
351 |  |
             public void generatingReportsView(File outputDirectory, List<String> formats, Properties viewProperties) {
352 | 1 |
                 log("Generating reports view to '" + outputDirectory + "' using formats '" + formats + "'"
353 |  |
                         + " and view properties '" + viewProperties + "'", MSG_INFO);
354 | 1 |
             }
355 |  |
356 |  |
             public void reportsViewGenerationFailed(File outputDirectory, List<String> formats, Properties viewProperties,
357 |  |
                     Throwable cause) {
358 | 1 |
                 log("Failed to generate reports view to '" + outputDirectory + "' using formats '" + formats + "'"
359 |  |
                         + " and view properties '" + viewProperties + "'", cause, MSG_WARN);
360 | 1 |
             }
361 |  |
362 |  |
             public void reportsViewGenerated(ReportsCount count) {
363 | 1 |
                 log("Reports view generated with " + count.getStories() + " stories (of which " + count.getStoriesPending()
364 |  |
                         + " pending) containing " + count.getScenarios() + " scenarios (of which "
365 |  |
                         + count.getScenariosPending() + " pending)", MSG_INFO);
366 | 1 |
                 if (count.getStoriesNotAllowed() > 0 || count.getScenariosNotAllowed() > 0) {
367 | 1 |
                     log("Meta filters excluded " + count.getStoriesNotAllowed() + " stories and  "
368 |  |
                             + count.getScenariosNotAllowed() + " scenarios", MSG_INFO);
369 |  |
                 }
370 | 1 |
             }
371 |  |
372 |  |
             public void reportsViewFailures(ReportsCount count) {
373 | 0 |
                 log("Failures in reports view: " + count.getScenariosFailed() + " scenarios failed", MSG_WARN);
374 | 0 |
             }
375 |  |
376 |  |
             public void reportsViewNotGenerated() {
377 | 1 |
                 log("Reports view not generated", MSG_INFO);
378 | 1 |
             }
379 |  |
380 |  |
             public void mappingStory(String storyPath, List<String> metaFilters) {
381 | 0 |
                 log("Mapping story " + storyPath + " with meta filters " + metaFilters, MSG_INFO);
382 | 0 |
             }
383 |  |
384 |  |
             public void generatingMapsView(File outputDirectory, StoryMaps storyMaps, Properties viewProperties) {
385 | 0 |
                 log("Generating maps view to '" + outputDirectory + "' using story maps '" + storyMaps + "'"
386 |  |
                         + " and view properties '" + viewProperties + "'", MSG_INFO);
387 | 0 |
             }
388 |  |
389 |  |
             public void mapsViewGenerationFailed(File outputDirectory, StoryMaps storyMaps, Properties viewProperties,
390 |  |
                     Throwable cause) {
391 | 0 |
                 log("Failed to generate maps view to '" + outputDirectory + "' using story maps '" + storyMaps + "'"
392 |  |
                         + " and view properties '" + viewProperties + "'", cause, MSG_WARN);
393 | 0 |
             }
394 |  |
395 |  |
             public void generatingNavigatorView(File outputDirectory, Properties viewProperties) {
396 | 0 |
                 log("Generating navigator view to '" + outputDirectory + "' using  properties '" + viewProperties + "'",
397 |  |
                         MSG_INFO);
398 | 0 |
             }
399 |  |
400 |  |
             public void navigatorViewGenerationFailed(File outputDirectory, Properties viewProperties, Throwable cause) {
401 | 0 |
                 log("Failed to generating navigator view to '" + outputDirectory + "' using  properties '" + viewProperties
402 |  |
                         + "'", cause, MSG_WARN);
403 | 0 |
             }
404 |  |
405 |  |
             public void navigatorViewNotGenerated() {
406 | 0 |
                 log("Navigator view not generated, as the CrossReference has not been declared in the StoryReporterBuilder",
407 |  |
                         MSG_WARN);
408 | 0 |
             }
409 |  |
410 |  |
             public void processingSystemProperties(Properties properties) {
411 | 0 |
                 log("Processing system properties " + properties, MSG_INFO);
412 | 0 |
             }
413 |  |
414 |  |
             public void systemPropertySet(String name, String value) {
415 | 0 |
                 log("System property '" + name + "' set to '" + value + "'", MSG_INFO);
416 | 0 |
             }
417 |  |
418 |  |
             public void storyTimeout(Story story, StoryDuration storyDuration) {
419 | 0 |
                 log("Story " + story.getPath() + " duration of " + storyDuration.getDurationInSecs()
420 |  |
                         + " seconds has exceeded timeout of " + storyDuration.getTimeoutInSecs() + " seconds", MSG_INFO);
421 | 0 |
             }
422 |  |
423 |  |
             public void usingThreads(int threads) {
424 | 0 |
                 log("Using " + threads + " threads", MSG_INFO);
425 | 0 |
             }
426 |  |
427 |  |
             public void usingExecutorService(ExecutorService executorService) {
428 | 0 |
                 log("Using executor service " + executorService, MSG_INFO);
429 | 0 |
             }
430 |  |
431 |  |
             public void usingControls(EmbedderControls embedderControls) {
432 | 0 |
                 log("Using controls " + embedderControls, MSG_INFO);
433 | 0 |
             }
434 |  |
435 |  |
             @Override
436 |  |
             public String toString() {
437 | 1 |
                 return this.getClass().getSimpleName();
438 |  |
             }
439 |  |
440 |  |
         }
441 |  |
442 |  |
         // Setters used by Task to inject dependencies
443 |  |
444 |  |
         public void setSourceDirectory(String sourceDirectory) {
445 | 5 |
             this.sourceDirectory = sourceDirectory;
446 | 5 |
         }
447 |  |
448 |  |
         public void setTestSourceDirectory(String testSourceDirectory) {
449 | 1 |
             this.testSourceDirectory = testSourceDirectory;
450 | 1 |
         }
451 |  |
452 |  |
         public void setOutputDirectory(String outputDirectory) {
453 | 2 |
             this.outputDirectory = outputDirectory;
454 | 2 |
         }
455 |  |
456 |  |
         public void setTestOutputDirectory(String testOutputDirectory) {
457 | 1 |
             this.testOutputDirectory = testOutputDirectory;
458 | 1 |
         }
459 |  |
460 |  |
         public void setScope(String scope) {
461 | 1 |
             this.scope = scope;
462 | 1 |
         }
463 |  |
464 |  |
         public void setIncludes(String includesCSV) {
465 | 5 |
             this.includes = asList(includesCSV.split(","));
466 | 5 |
         }
467 |  |
468 |  |
         public void setExcludes(String excludesCSV) {
469 | 5 |
             this.excludes = asList(excludesCSV.split(","));
470 | 5 |
         }
471 |  |
472 |  |
         public void setBatch(boolean batch) {
473 | 1 |
             this.batch = batch;
474 | 1 |
         }
475 |  |
476 |  |
         public void setSkip(boolean skip) {
477 | 1 |
             this.skip = skip;
478 | 1 |
         }
479 |  |
480 |  |
         public void setIgnoreFailureInStories(boolean ignoreFailureInStories) {
481 | 1 |
             this.ignoreFailureInStories = ignoreFailureInStories;
482 | 1 |
         }
483 |  |
484 |  |
         public void setIgnoreFailureInView(boolean ignoreFailureInView) {
485 | 1 |
             this.ignoreFailureInView = ignoreFailureInView;
486 | 1 |
         }
487 |  |
488 |  |
         public void setGenerateViewAfterStories(boolean generateViewAfterStories) {
489 | 1 |
             this.generateViewAfterStories = generateViewAfterStories;
490 | 1 |
         }
491 |  |
492 |  |
         public void setVerboseFailures(boolean verboseFailures) {
493 | 1 |
             this.verboseFailures = verboseFailures;
494 | 1 |
         }
495 |  |
496 |  |
         public void setVerboseFiltering(boolean verboseFiltering) {
497 | 1 |
             this.verboseFiltering = verboseFiltering;
498 | 1 |
         }
499 |  |
500 |  |
         public void setStoryTimeoutInSecs(long storyTimeoutInSecs) {
501 | 1 |
             this.storyTimeoutInSecs = storyTimeoutInSecs;
502 | 1 |
         }
503 |  |
504 |  |
         public void setThreads(int threads) {
505 | 1 |
             this.threads = threads;
506 | 1 |
         }
507 |  |
508 |  |
         public void setEmbedderClass(String embedderClass) {
509 | 1 |
             this.embedderClass = embedderClass;
510 | 1 |
         }
511 |  |
512 |  |
         public void setExecutorsClass(String executorsClass) {
513 | 1 |
             this.executorsClass = executorsClass;
514 | 1 |
         }
515 |  |
516 |  |
         public void setInjectableEmbedderClass(String injectableEmbedderClass) {
517 | 1 |
             this.injectableEmbedderClass = injectableEmbedderClass;
518 | 1 |
         }
519 |  |
520 |  |
         public void setAnnotatedEmbedderRunnerClass(String annotatedEmbedderRunnerClass) {
521 | 0 |
             this.annotatedEmbedderRunnerClass = annotatedEmbedderRunnerClass;
522 | 0 |
         }
523 |  |
524 |  |
         public void setStoryFinderClass(String storyFinderClass) {
525 | 1 |
             this.storyFinderClass = storyFinderClass;
526 | 1 |
         }
527 |  |
528 |  |
         public void setMetaFilters(String metaFiltersCSV) {
529 | 0 |
             this.metaFilters = asList(metaFiltersCSV.split(","));
530 | 0 |
         }
531 |  |
532 |  |
         public void setSystemProperties(String systemPropertiesCSV) {
533 | 1 |
             this.systemProperties = loadProperties(systemPropertiesCSV);
534 | 1 |
         }
535 |  |
536 |  |
         private Properties loadProperties(String systemPropertiesCSV) {
537 | 1 |
             Properties properties = new Properties();
538 |  |
             try {
539 | 1 |
                 properties.load(new StringInputStream(systemPropertiesCSV.replace(",", "\n")));
540 | 0 |
             } catch (IOException e) {
541 |  |
                 // return empty map
542 | 1 |
             }
543 | 1 |
             return properties;
544 |  |
         }
545 |  |
546 |  |
     }