<commit_before>package org.jbehave.core.embedder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.embedder.PerformableTree.PerformableRoot;
import org.jbehave.core.embedder.PerformableTree.RunContext;
import org.jbehave.core.failures.BatchFailures;
import org.jbehave.core.model.Story;
import org.jbehave.core.model.StoryDuration;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.StepCollector.Stage;

/**
 * Manages the execution and outcomes of running stories. While each story is
 * run by the {@link StoryRunner}, the manager is responsible for the concurrent
 * submission and monitoring of their execution via the {@link ExecutorService}.
 */
public class StoryManager {

    private final Configuration configuration;
    private final EmbedderControls embedderControls;
    private final EmbedderMonitor embedderMonitor;
    private final ExecutorService executorService;
    private final InjectableStepsFactory stepsFactory;
    private final PerformableTree performableTree;
    private final Map<String, RunningStory> runningStories = new HashMap<String, RunningStory>();
    private final Map<MetaFilter, List<Story>> excludedStories = new HashMap<MetaFilter, List<Story>>();
    private RunContext context;

    public StoryManager(Configuration configuration, InjectableStepsFactory stepsFactory,
            EmbedderControls embedderControls, EmbedderMonitor embedderMonitor, ExecutorService executorService,
            PerformableTree performableTree) {
        this.configuration = configuration;
        this.embedderControls = embedderControls;
        this.embedderMonitor = embedderMonitor;
        this.executorService = executorService;
        this.stepsFactory = stepsFactory;
        this.performableTree = performableTree;
    }

    public Story storyOfPath(String storyPath) {
        return performableTree.storyOfPath(configuration, storyPath);
    }

    public Story storyOfText(String storyAsText, String storyId) {
        return performableTree.storyOfText(configuration, storyAsText, storyId);
    }

    public void clear() {
        runningStories.clear();
    }

    public PerformableRoot performableRoot(){
        return performableTree.getRoot();
    }
    
    public List<StoryOutcome> outcomes() {
        List<StoryOutcome> outcomes = new ArrayList<StoryOutcome>();
        for (RunningStory story : runningStories.values()) {
            outcomes.add(new StoryOutcome(story));
        }
        return outcomes;
    }

    public void runStories(List<String> storyPaths, MetaFilter filter, BatchFailures failures) {
        // create new run context
        context = performableTree.newRunContext(configuration, stepsFactory, filter, failures);
        performableTree.addStories(context, storyPaths);
        
        performStories(context, performableTree, storyPaths, filter, failures);
    }

    public void performStories(RunContext context, PerformableTree performableTree, List<String> storyPaths, MetaFilter filter, BatchFailures failures) {
        // before stories
        performableTree.performBeforeOrAfterStories(context, Stage.BEFORE);
        
        // stories as paths
        runningStoriesAsPaths(context, storyPaths);        
        waitUntilAllDoneOrFailed(context);
        List<Story> notAllowed = notAllowedBy(filter);
        if (!notAllowed.isEmpty()) {
            embedderMonitor.storiesNotAllowed(notAllowed, filter, embedderControls.verboseFiltering());
        }

        // after stories
        performableTree.performBeforeOrAfterStories(context, Stage.AFTER);     
        
        // collect failures
        failures.putAll(context.getFailures());
    }

    public Map<String, RunningStory> runningStoriesAsPaths(RunContext context, List<String> storyPaths) {
        for (String storyPath : storyPaths) {
            filterRunning(context, storyOfPath(storyPath));
        }
        return runningStories;
    }

    public Map<String, RunningStory> runningStories(RunContext context, List<Story> stories) {
        for (Story story : stories) {
            filterRunning(context, story);
        }
        return runningStories;
    }

    private void filterRunning(RunContext context, Story story) {
        FilteredStory filteredStory = context.filter(story);
        if (filteredStory.allowed()) {
            runningStories.put(story.getPath(), runningStory(story));
        } else {
            notAllowedBy(context.getFilter()).add(story);
        }<commit_msg>JBEHAVE-777:  Reuse filter from run context.<commit_after>package org.jbehave.core.embedder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.embedder.PerformableTree.PerformableRoot;
import org.jbehave.core.embedder.PerformableTree.RunContext;
import org.jbehave.core.failures.BatchFailures;
import org.jbehave.core.model.Story;
import org.jbehave.core.model.StoryDuration;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.StepCollector.Stage;

/**
 * Manages the execution and outcomes of running stories. While each story is
 * run by the {@link StoryRunner}, the manager is responsible for the concurrent
 * submission and monitoring of their execution via the {@link ExecutorService}.
 */
public class StoryManager {

    private final Configuration configuration;
    private final EmbedderControls embedderControls;
    private final EmbedderMonitor embedderMonitor;
    private final ExecutorService executorService;
    private final InjectableStepsFactory stepsFactory;
    private final PerformableTree performableTree;
    private final Map<String, RunningStory> runningStories = new HashMap<String, RunningStory>();
    private final Map<MetaFilter, List<Story>> excludedStories = new HashMap<MetaFilter, List<Story>>();
    private RunContext context;

    public StoryManager(Configuration configuration, InjectableStepsFactory stepsFactory,
            EmbedderControls embedderControls, EmbedderMonitor embedderMonitor, ExecutorService executorService,
            PerformableTree performableTree) {
        this.configuration = configuration;
        this.embedderControls = embedderControls;
        this.embedderMonitor = embedderMonitor;
        this.executorService = executorService;
        this.stepsFactory = stepsFactory;
        this.performableTree = performableTree;
    }

    public Story storyOfPath(String storyPath) {
        return performableTree.storyOfPath(configuration, storyPath);
    }

    public Story storyOfText(String storyAsText, String storyId) {
        return performableTree.storyOfText(configuration, storyAsText, storyId);
    }

    public void clear() {
        runningStories.clear();
    }

    public PerformableRoot performableRoot(){
        return performableTree.getRoot();
    }
    
    public List<StoryOutcome> outcomes() {
        List<StoryOutcome> outcomes = new ArrayList<StoryOutcome>();
        for (RunningStory story : runningStories.values()) {
            outcomes.add(new StoryOutcome(story));
        }
        return outcomes;
    }

    public void runStories(List<String> storyPaths, MetaFilter filter, BatchFailures failures) {
        // create new run context
        context = performableTree.newRunContext(configuration, stepsFactory, filter, failures);
        
        // add stories        
        performableTree.addStories(context, storyPaths);

        // perform stories
        performStories(context, performableTree, storyPaths);
        
        // collect failures
        failures.putAll(context.getFailures());       
        
    }

    public void performStories(RunContext context, PerformableTree performableTree, List<String> storyPaths) {
        // before stories
        performableTree.performBeforeOrAfterStories(context, Stage.BEFORE);
        
        // stories as paths
        runningStoriesAsPaths(context, storyPaths);        
        waitUntilAllDoneOrFailed(context);
        MetaFilter filter = context.filter();
		List<Story> notAllowed = notAllowedBy(filter);
        if (!notAllowed.isEmpty()) {
            embedderMonitor.storiesNotAllowed(notAllowed, filter, embedderControls.verboseFiltering());
        }

        // after stories
        performableTree.performBeforeOrAfterStories(context, Stage.AFTER);     
    }

    public Map<String, RunningStory> runningStoriesAsPaths(RunContext context, List<String> storyPaths) {
        for (String storyPath : storyPaths) {
            filterRunning(context, storyOfPath(storyPath));
        }
        return runningStories;
    }

    public Map<String, RunningStory> runningStories(RunContext context, List<Story> stories) {
        for (Story story : stories) {
            filterRunning(context, story);
        }
        return runningStories;
    }

    private void filterRunning(RunContext context, Story story) {
        FilteredStory filteredStory = context.filter(story);
        if (filteredStory.allowed()) {
            runningStories.put(story.getPath(), runningStory(story));
        } else {
            notAllowedBy(context.getFilter()).add(story);
        }
{'fraction_non_alphanumeric': 0.08241247547247754, 'fraction_numerical': 0.0003098213363626975, 'mean_word_length': 3.5062819916240113, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '680031', 'n_tokens_mistral': 2542, 'n_tokens_neox': 2487, 'n_words': 578}