Coverage Report - org.jbehave.core.embedder.Embedder
 
Classes in this File Line Coverage Branch Coverage Complexity
Embedder
89%
210/235
75%
60/80
1.867
Embedder$AnnotatedEmbedderRunFailed
100%
2/2
N/A
1.867
Embedder$EmbedderFailureStrategy
N/A
N/A
1.867
Embedder$RunningEmbeddablesFailed
100%
4/4
N/A
1.867
Embedder$RunningStoriesFailed
100%
4/4
N/A
1.867
Embedder$ThrowingRunningStoriesFailed
100%
3/3
N/A
1.867
Embedder$ViewGenerationFailed
50%
2/4
N/A
1.867
 
 1  
 package org.jbehave.core.embedder;
 2  
 
 3  
 import java.io.File;
 4  
 import java.util.ArrayList;
 5  
 import java.util.Arrays;
 6  
 import java.util.List;
 7  
 import java.util.Properties;
 8  
 import java.util.concurrent.ExecutorService;
 9  
 import java.util.concurrent.ThreadPoolExecutor;
 10  
 
 11  
 import org.apache.commons.lang.StringUtils;
 12  
 import org.apache.commons.lang.builder.ToStringBuilder;
 13  
 import org.apache.commons.lang.builder.ToStringStyle;
 14  
 import org.jbehave.core.ConfigurableEmbedder;
 15  
 import org.jbehave.core.Embeddable;
 16  
 import org.jbehave.core.configuration.Configuration;
 17  
 import org.jbehave.core.configuration.MostUsefulConfiguration;
 18  
 import org.jbehave.core.embedder.executors.FixedThreadExecutors;
 19  
 import org.jbehave.core.failures.BatchFailures;
 20  
 import org.jbehave.core.failures.FailingUponPendingStep;
 21  
 import org.jbehave.core.junit.AnnotatedEmbedderRunner;
 22  
 import org.jbehave.core.junit.AnnotatedEmbedderUtils;
 23  
 import org.jbehave.core.model.Story;
 24  
 import org.jbehave.core.model.StoryMaps;
 25  
 import org.jbehave.core.reporters.ReportsCount;
 26  
 import org.jbehave.core.reporters.StepdocReporter;
 27  
 import org.jbehave.core.reporters.StoryReporterBuilder;
 28  
 import org.jbehave.core.reporters.ViewGenerator;
 29  
 import org.jbehave.core.steps.CandidateSteps;
 30  
 import org.jbehave.core.steps.InjectableStepsFactory;
 31  
 import org.jbehave.core.steps.ProvidedStepsFactory;
 32  
 import org.jbehave.core.steps.StepFinder;
 33  
 import org.jbehave.core.steps.Stepdoc;
 34  
 
 35  
 /**
 36  
  * The Embedder is a facade allowing all functionality to be embedded into other
 37  
  * run contexts, such as IDEs (e.g. via JUnit support) or CLIs (via Ant or
 38  
  * Maven).
 39  
  */
 40  
 public class Embedder {
 41  
 
 42  
     private StoryMapper storyMapper;
 43  
     private StoryRunner storyRunner;
 44  
     private EmbedderMonitor embedderMonitor;
 45  74
     private EmbedderClassLoader classLoader = new EmbedderClassLoader(this.getClass().getClassLoader());
 46  74
     private EmbedderControls embedderControls = new EmbedderControls();
 47  74
     private EmbedderFailureStrategy embedderFailureStrategy = new ThrowingRunningStoriesFailed();
 48  74
     private Configuration configuration = new MostUsefulConfiguration();
 49  74
     private List<CandidateSteps> candidateSteps = new ArrayList<CandidateSteps>();
 50  
     private InjectableStepsFactory stepsFactory;
 51  74
     private List<String> metaFilters = Arrays.asList();
 52  74
     private Properties systemProperties = new Properties();
 53  
     private ExecutorService executorService;
 54  
     private boolean executorServiceCreated;
 55  
     private StoryManager storyManager;
 56  
 
 57  
     public Embedder() {
 58  41
         this(new StoryMapper(), new StoryRunner(), new PrintStreamEmbedderMonitor());
 59  41
     }
 60  
 
 61  74
     public Embedder(StoryMapper storyMapper, StoryRunner storyRunner, EmbedderMonitor embedderMonitor) {
 62  74
         this.storyMapper = storyMapper;
 63  74
         this.storyRunner = storyRunner;
 64  74
         this.embedderMonitor = embedderMonitor;
 65  74
     }
 66  
 
 67  
     public void mapStoriesAsPaths(List<String> storyPaths) {
 68  1
         EmbedderControls embedderControls = embedderControls();
 69  1
         embedderMonitor.usingControls(embedderControls);
 70  
 
 71  1
         if (embedderControls.skip()) {
 72  0
             embedderMonitor.storiesSkipped(storyPaths);
 73  0
             return;
 74  
         }
 75  
 
 76  1
         processSystemProperties();
 77  
 
 78  1
         StoryManager storyManager = storyManager();
 79  1
         for (String storyPath : storyPaths) {
 80  2
             Story story = storyManager.storyOfPath(storyPath);
 81  2
             embedderMonitor.mappingStory(storyPath, metaFilters);
 82  2
             storyMapper.map(story, new MetaFilter(""));
 83  2
             for (String filter : metaFilters) {
 84  0
                 storyMapper.map(story, new MetaFilter(filter));
 85  
             }
 86  2
         }
 87  
 
 88  1
         generateMapsView(storyMapper.getStoryMaps());
 89  
 
 90  1
     }
 91  
 
 92  
     private void generateMapsView(StoryMaps storyMaps) {
 93  1
         Configuration configuration = configuration();
 94  1
         StoryReporterBuilder builder = configuration.storyReporterBuilder();
 95  1
         File outputDirectory = builder.outputDirectory();
 96  1
         Properties viewResources = builder.viewResources();
 97  1
         ViewGenerator viewGenerator = configuration.viewGenerator();
 98  
         try {
 99  1
             embedderMonitor.generatingMapsView(outputDirectory, storyMaps, viewResources);
 100  1
             viewGenerator.generateMapsView(outputDirectory, storyMaps, viewResources);
 101  0
         } catch (RuntimeException e) {
 102  0
             embedderMonitor.mapsViewGenerationFailed(outputDirectory, storyMaps, viewResources, e);
 103  0
             throw new ViewGenerationFailed(outputDirectory, storyMaps, viewResources, e);
 104  1
         }
 105  1
     }
 106  
 
 107  
     public void runAsEmbeddables(List<String> classNames) {
 108  11
         EmbedderControls embedderControls = embedderControls();
 109  11
         embedderMonitor.usingControls(embedderControls);
 110  
 
 111  11
         if (embedderControls.skip()) {
 112  1
             embedderMonitor.embeddablesSkipped(classNames);
 113  1
             return;
 114  
         }
 115  
 
 116  10
         BatchFailures failures = new BatchFailures(embedderControls.verboseFailures());
 117  10
         for (Embeddable embeddable : embeddables(classNames, classLoader())) {
 118  16
             String name = embeddable.getClass().getName();
 119  
             try {
 120  16
                 embedderMonitor.runningEmbeddable(name);
 121  16
                 embeddable.useEmbedder(this);
 122  16
                 embeddable.run();
 123  5
             } catch (Throwable e) {
 124  5
                 if (embedderControls.batch()) {
 125  
                     // collect and postpone decision to throw exception
 126  2
                     failures.put(name, e);
 127  
                 } else {
 128  3
                     if (ignoreFailure(embedderControls)) {
 129  1
                         embedderMonitor.embeddableFailed(name, e);
 130  
                     } else {
 131  2
                         throw new RunningEmbeddablesFailed(name, e);
 132  
                     }
 133  
                 }
 134  11
             }
 135  14
         }
 136  
 
 137  8
         if (embedderControls.batch() && failures.size() > 0) {
 138  2
             if (ignoreFailure(embedderControls)) {
 139  1
                 embedderMonitor.batchFailed(failures);
 140  
             } else {
 141  1
                 throw new RunningEmbeddablesFailed(failures);
 142  
             }
 143  
         }
 144  
 
 145  7
     }
 146  
 
 147  
     private boolean ignoreFailure(EmbedderControls embedderControls) {
 148  5
         boolean ignore = embedderControls.ignoreFailureInStories();
 149  5
         if (embedderControls.generateViewAfterStories()) {
 150  5
             ignore = ignore && embedderControls.ignoreFailureInView();
 151  
         }
 152  5
         return ignore;
 153  
     }
 154  
 
 155  
     private List<Embeddable> embeddables(List<String> classNames, EmbedderClassLoader classLoader) {
 156  10
         List<Embeddable> embeddables = new ArrayList<Embeddable>();
 157  10
         for (String className : classNames) {
 158  18
             if (!classLoader.isAbstract(className)) {
 159  17
                 embeddables.add(classLoader.newInstance(Embeddable.class, className));
 160  
             }
 161  
         }
 162  10
         return embeddables;
 163  
     }
 164  
 
 165  
     public void runStoriesWithAnnotatedEmbedderRunner(List<String> classNames) {
 166  4
         EmbedderClassLoader classLoader = classLoader();
 167  4
         for (String className : classNames) {
 168  4
             embedderMonitor.runningWithAnnotatedEmbedderRunner(className);
 169  4
             AnnotatedEmbedderRunner runner = AnnotatedEmbedderUtils.annotatedEmbedderRunner(className, classLoader);
 170  
             try {
 171  3
                 Object annotatedInstance = runner.createTest();
 172  3
                 if (annotatedInstance instanceof Embeddable) {
 173  2
                     ((Embeddable) annotatedInstance).run();
 174  
                 } else {
 175  1
                     embedderMonitor.annotatedInstanceNotOfType(annotatedInstance, Embeddable.class);
 176  
                 }
 177  1
             } catch (Throwable e) {
 178  1
                 throw new AnnotatedEmbedderRunFailed(runner, e);
 179  2
             }
 180  2
         }
 181  2
     }
 182  
 
 183  
     public void runStoriesAsPaths(List<String> storyPaths) {
 184  
 
 185  12
         processSystemProperties();
 186  
 
 187  12
         embedderMonitor.usingControls(embedderControls);
 188  
 
 189  12
         if (embedderControls.skip()) {
 190  1
             embedderMonitor.storiesSkipped(storyPaths);
 191  1
             return;
 192  
         }
 193  
 
 194  
         try {
 195  
 
 196  
             // set up run context
 197  11
             StoryManager storyManager = createStoryManager();
 198  11
             MetaFilter filter = metaFilter();
 199  11
             BatchFailures failures = new BatchFailures(embedderControls.verboseFailures());
 200  
 
 201  
             // run stories
 202  11
             storyManager.runStories(storyPaths, filter, failures);
 203  
 
 204  
             // handle any failures
 205  11
             handleFailures(failures);
 206  
 
 207  
         } finally {
 208  
 
 209  
             // generate reports view regardless of failures in running stories
 210  
             // (if configured to do so)
 211  11
             if (embedderControls.generateViewAfterStories()) {
 212  10
                 generateReportsView();
 213  
             }
 214  11
             shutdownExecutorService();
 215  
 
 216  6
         }
 217  6
     }
 218  
 
 219  
     private void handleFailures(BatchFailures failures) {
 220  11
         if (failures.size() > 0) {
 221  5
             if (embedderControls.ignoreFailureInStories()) {
 222  0
                 embedderMonitor.batchFailed(failures);
 223  
             } else {
 224  5
                 embedderFailureStrategy.handleFailures(failures);
 225  
             }
 226  
         }
 227  6
     }
 228  
 
 229  
     public void generateReportsView() {
 230  10
         StoryReporterBuilder builder = configuration().storyReporterBuilder();
 231  10
         File outputDirectory = builder.outputDirectory();
 232  10
         List<String> formatNames = builder.formatNames(true);
 233  10
         generateReportsView(outputDirectory, formatNames, builder.viewResources());
 234  10
     }
 235  
 
 236  
     public void generateReportsView(File outputDirectory, List<String> formats, Properties viewResources) {
 237  
 
 238  19
         if (embedderControls.skip()) {
 239  1
             embedderMonitor.reportsViewNotGenerated();
 240  1
             return;
 241  
         }
 242  18
         ViewGenerator viewGenerator = configuration().viewGenerator();
 243  
         try {
 244  18
             embedderMonitor.generatingReportsView(outputDirectory, formats, viewResources);
 245  18
             viewGenerator.generateReportsView(outputDirectory, formats, viewResources);
 246  1
         } catch (RuntimeException e) {
 247  1
             embedderMonitor.reportsViewGenerationFailed(outputDirectory, formats, viewResources, e);
 248  1
             throw new ViewGenerationFailed(outputDirectory, formats, viewResources, e);
 249  17
         }
 250  17
         ReportsCount count = viewGenerator.getReportsCount();
 251  17
         embedderMonitor.reportsViewGenerated(count);
 252  17
         handleFailures(count);
 253  
 
 254  13
     }
 255  
 
 256  
     private void handleFailures(ReportsCount count) {
 257  17
         boolean failed = count.failed();
 258  17
         if (configuration().pendingStepStrategy() instanceof FailingUponPendingStep) {
 259  1
             failed = failed || count.pending();
 260  
         }
 261  17
         if (failed) {
 262  6
             if (embedderControls.ignoreFailureInView()) {
 263  1
                 embedderMonitor.reportsViewFailures(count);
 264  
             } else {
 265  5
                 embedderFailureStrategy.handleFailures(count);
 266  
             }
 267  
         }
 268  13
     }
 269  
 
 270  
     public void generateCrossReference() {
 271  2
         StoryReporterBuilder builder = configuration().storyReporterBuilder();
 272  2
         if (builder.hasCrossReference()) {
 273  1
             builder.crossReference().outputToFiles(builder);
 274  
         }
 275  2
     }
 276  
 
 277  
     public void reportStepdocs() {
 278  1
         reportStepdocs(configuration(), candidateSteps());
 279  1
     }
 280  
 
 281  
     public void reportStepdocsAsEmbeddables(List<String> classNames) {
 282  0
         EmbedderControls embedderControls = embedderControls();
 283  0
         if (embedderControls.skip()) {
 284  0
             embedderMonitor.embeddablesSkipped(classNames);
 285  0
             return;
 286  
         }
 287  
 
 288  0
         for (Embeddable embeddable : embeddables(classNames, classLoader())) {
 289  0
             if (embeddable instanceof ConfigurableEmbedder) {
 290  0
                 ConfigurableEmbedder configurableEmbedder = (ConfigurableEmbedder) embeddable;
 291  0
                 List<CandidateSteps> steps = configurableEmbedder.candidateSteps();
 292  0
                 if (steps.isEmpty()) {
 293  0
                     steps = configurableEmbedder.stepsFactory().createCandidateSteps();
 294  
                 }
 295  0
                 reportStepdocs(configurableEmbedder.configuration(), steps);
 296  0
             } else {
 297  0
                 embedderMonitor.embeddableNotConfigurable(embeddable.getClass().getName());
 298  
             }
 299  
         }
 300  0
     }
 301  
 
 302  
     public void reportStepdocs(Configuration configuration, List<CandidateSteps> candidateSteps) {
 303  1
         StepFinder finder = configuration.stepFinder();
 304  1
         StepdocReporter reporter = configuration.stepdocReporter();
 305  1
         List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
 306  1
         reporter.stepdocs(finder.stepdocs(candidateSteps), stepsInstances);
 307  1
     }
 308  
 
 309  
     public void reportMatchingStepdocs(String stepAsString) {
 310  3
         Configuration configuration = configuration();
 311  3
         List<CandidateSteps> candidateSteps = candidateSteps();
 312  3
         StepFinder finder = configuration.stepFinder();
 313  3
         StepdocReporter reporter = configuration.stepdocReporter();
 314  3
         List<Stepdoc> matching = finder.findMatching(stepAsString, candidateSteps);
 315  3
         List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
 316  3
         reporter.stepdocsMatching(stepAsString, matching, stepsInstances);
 317  3
     }
 318  
 
 319  
     public void processSystemProperties() {
 320  15
         Properties properties = systemProperties();
 321  15
         embedderMonitor.processingSystemProperties(properties);
 322  15
         if (!properties.isEmpty()) {
 323  1
             for (Object key : properties.keySet()) {
 324  2
                 String name = (String) key;
 325  2
                 String value = properties.getProperty(name);
 326  2
                 System.setProperty(name, value);
 327  2
                 embedderMonitor.systemPropertySet(name, value);
 328  2
             }
 329  
         }
 330  15
     }
 331  
 
 332  
     public EmbedderClassLoader classLoader() {
 333  14
         return classLoader;
 334  
     }
 335  
 
 336  
     public Configuration configuration() {
 337  102
         configureThreads(configuration, embedderControls.threads());
 338  102
         return configuration;
 339  
     }
 340  
 
 341  
     public List<CandidateSteps> candidateSteps() {
 342  15
         return candidateSteps;
 343  
     }
 344  
 
 345  
     public InjectableStepsFactory stepsFactory() {
 346  23
         if (stepsFactory == null) {
 347  12
             stepsFactory = new ProvidedStepsFactory(candidateSteps);
 348  
         }
 349  23
         return stepsFactory;
 350  
     }
 351  
 
 352  
     public EmbedderControls embedderControls() {
 353  36
         return embedderControls;
 354  
     }
 355  
 
 356  
     public EmbedderMonitor embedderMonitor() {
 357  14
         return embedderMonitor;
 358  
     }
 359  
 
 360  
     public EmbedderFailureStrategy embedderFailureStrategy() {
 361  0
         return embedderFailureStrategy;
 362  
     }
 363  
 
 364  
     public boolean hasExecutorService() {
 365  1
         return executorService != null;
 366  
     }
 367  
 
 368  
     public ExecutorService executorService() {
 369  12
         if (executorService == null) {
 370  12
             executorService = createExecutorService();
 371  12
             executorServiceCreated = true;
 372  
         }
 373  12
         return executorService;
 374  
     }
 375  
 
 376  
     /**
 377  
      * Creates a {@link ThreadPoolExecutor} using the number of threads defined
 378  
      * in the {@link EmbedderControls#threads()}
 379  
      * 
 380  
      * @return An ExecutorService
 381  
      */
 382  
     private ExecutorService createExecutorService() {
 383  12
         return new FixedThreadExecutors().create(embedderControls);
 384  
     }
 385  
 
 386  
     /**
 387  
      * Shuts down executor service, if it was created by Embedder.
 388  
      * ExecutorServices provided by the
 389  
      * {@link #useExecutorService(ExecutorService)} need to be managed by the
 390  
      * provider.
 391  
      */
 392  
     protected void shutdownExecutorService() {
 393  11
         if (executorServiceCreated) {
 394  11
             executorService.shutdownNow();
 395  11
             executorService = null;
 396  11
             executorServiceCreated = false;
 397  
         }
 398  11
     }
 399  
 
 400  
     public StoryManager storyManager() {
 401  1
         if (storyManager == null) {
 402  1
             storyManager = createStoryManager();
 403  
         }
 404  1
         return storyManager;
 405  
     }
 406  
 
 407  
     private StoryManager createStoryManager() {
 408  12
         return new StoryManager(configuration(), embedderControls(), embedderMonitor(), executorService(),
 409  
                 stepsFactory(), storyRunner());
 410  
     }
 411  
 
 412  
     private void configureThreads(Configuration configuration, int threads) {
 413  102
         StoryReporterBuilder reporterBuilder = configuration.storyReporterBuilder();
 414  102
         reporterBuilder.withMultiThreading(threads > 1);
 415  102
         configuration.useStoryReporterBuilder(reporterBuilder);
 416  102
     }
 417  
 
 418  
     public List<String> metaFilters() {
 419  4
         return metaFilters;
 420  
     }
 421  
 
 422  
     public MetaFilter metaFilter() {
 423  11
         return new MetaFilter(StringUtils.join(metaFilters, " "), embedderMonitor);
 424  
     }
 425  
 
 426  
     public StoryRunner storyRunner() {
 427  14
         return storyRunner;
 428  
     }
 429  
 
 430  
     public Properties systemProperties() {
 431  18
         return systemProperties;
 432  
     }
 433  
 
 434  
     public void useClassLoader(EmbedderClassLoader classLoader) {
 435  14
         this.classLoader = classLoader;
 436  14
     }
 437  
 
 438  
     public void useConfiguration(Configuration configuration) {
 439  17
         this.configuration = configuration;
 440  17
     }
 441  
 
 442  
     public void useCandidateSteps(List<CandidateSteps> candidateSteps) {
 443  10
         this.candidateSteps = candidateSteps;
 444  10
     }
 445  
 
 446  
     public void useStepsFactory(InjectableStepsFactory stepsFactory) {
 447  10
         this.stepsFactory = stepsFactory;
 448  10
     }
 449  
 
 450  
     public void useEmbedderControls(EmbedderControls embedderControls) {
 451  33
         this.embedderControls = embedderControls;
 452  33
     }
 453  
 
 454  
     public void useEmbedderFailureStrategy(EmbedderFailureStrategy failureStategy) {
 455  1
         this.embedderFailureStrategy = failureStategy;
 456  1
     }
 457  
 
 458  
     public void useEmbedderMonitor(EmbedderMonitor embedderMonitor) {
 459  1
         this.embedderMonitor = embedderMonitor;
 460  1
     }
 461  
 
 462  
     public void useExecutorService(ExecutorService executorService) {
 463  0
         this.executorService = executorService;
 464  0
         embedderMonitor.usingExecutorService(executorService);
 465  0
     }
 466  
 
 467  
     public void useMetaFilters(List<String> metaFilters) {
 468  4
         this.metaFilters = metaFilters;
 469  4
     }
 470  
 
 471  
     public void useStoryRunner(StoryRunner storyRunner) {
 472  1
         this.storyRunner = storyRunner;
 473  1
     }
 474  
 
 475  
     public void useSystemProperties(Properties systemProperties) {
 476  2
         this.systemProperties = systemProperties;
 477  2
     }
 478  
 
 479  
     @Override
 480  
     public String toString() {
 481  1
         return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
 482  
     }
 483  
 
 484  
     public static interface EmbedderFailureStrategy {
 485  
 
 486  
         void handleFailures(BatchFailures failures);
 487  
 
 488  
         void handleFailures(ReportsCount count);
 489  
 
 490  
     }
 491  
 
 492  74
     public static class ThrowingRunningStoriesFailed implements EmbedderFailureStrategy {
 493  
 
 494  
         public void handleFailures(BatchFailures failures) {
 495  5
             throw new RunningStoriesFailed(failures);
 496  
         }
 497  
 
 498  
         public void handleFailures(ReportsCount count) {
 499  4
             throw new RunningStoriesFailed(count);
 500  
         }
 501  
 
 502  
     }
 503  
 
 504  
     @SuppressWarnings("serial")
 505  
     public static class AnnotatedEmbedderRunFailed extends RuntimeException {
 506  
 
 507  
         public AnnotatedEmbedderRunFailed(AnnotatedEmbedderRunner runner, Throwable cause) {
 508  1
             super("Annotated embedder run failed with runner " + runner.toString(), cause);
 509  1
         }
 510  
 
 511  
     }
 512  
 
 513  
     @SuppressWarnings("serial")
 514  
     public static class RunningEmbeddablesFailed extends RuntimeException {
 515  
 
 516  
         public RunningEmbeddablesFailed(String name, Throwable failure) {
 517  2
             super("Failure in running embeddable: " + name, failure);
 518  2
         }
 519  
 
 520  
         public RunningEmbeddablesFailed(BatchFailures failures) {
 521  1
             super("Failures in running embeddables: " + failures);
 522  1
         }
 523  
 
 524  
     }
 525  
 
 526  
     @SuppressWarnings("serial")
 527  
     public static class RunningStoriesFailed extends RuntimeException {
 528  
 
 529  
         public RunningStoriesFailed(ReportsCount reportsCount) {
 530  4
             super("Failures in running stories: " + reportsCount);
 531  4
         }
 532  
 
 533  
         public RunningStoriesFailed(BatchFailures failures) {
 534  5
             super("Failures in running stories: " + failures);
 535  5
         }
 536  
 
 537  
     }
 538  
 
 539  
     @SuppressWarnings("serial")
 540  
     public static class ViewGenerationFailed extends RuntimeException {
 541  
         public ViewGenerationFailed(File outputDirectory, List<String> formats, Properties viewResources,
 542  
                 RuntimeException cause) {
 543  1
             super("View generation failed to " + outputDirectory + " for formats " + formats + " and resources "
 544  
                     + viewResources, cause);
 545  1
         }
 546  
 
 547  
         public ViewGenerationFailed(File outputDirectory, StoryMaps storyMaps, Properties viewResources,
 548  
                 RuntimeException cause) {
 549  0
             super("View generation failed to " + outputDirectory + " for story maps " + storyMaps + " for resources "
 550  
                     + viewResources, cause);
 551  0
         }
 552  
     }
 553  
 
 554  
 }