<commit_before>package net.ijus.nidi.builder

import groovy.transform.CompileStatic
import net.ijus.nidi.Configuration
import net.ijus.nidi.Context
import net.ijus.nidi.ContextConfig
import net.ijus.nidi.InvalidConfigurationException
import net.ijus.nidi.bindings.Scope
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * Created by pfried on 7/2/14.
 */

@CompileStatic
public class ContextBuilder {
	static final Logger log = LoggerFactory.getLogger(ContextBuilder)

	boolean defaultScopeChanged = false

	Scope defaultScope = Scope.ALWAYS_CREATE_NEW
	Map<Class, BindingBuilder> ctxBindings = [:]

	Context ctx = new Context()

	BindingBuilder bind(Class clazz){
		BindingBuilder bb = new BindingBuilder(clazz, this)
		ctxBindings.put(clazz, bb)
		bb
	}

	void setDefaultScope(Scope newScope) {
		this.defaultScope = newScope
		this.defaultScopeChanged = true
	}

	void inheritFrom(String fqcn){
		Class configClass
		try {
			configClass = Class.forName(fqcn)
		} catch (ClassNotFoundException e) {
			throw new InvalidConfigurationException("Tried to inherit from: ${fqcn}, but the class could not be found", e)
		}
		inheritFrom(configClass)
	}

	void inheritFrom(Class configClass) {
		if (!ContextConfig.isAssignableFrom(configClass)) {
			throw new InvalidConfigurationException("Tried to inherit from: ${configClass.name}, but that class does not immplement ContextConfig")
		}
		ContextConfig config
		try {
			config = configClass.newInstance() as ContextConfig
		} catch (InstantiationException | IllegalAccessException e) {
			throw new InvalidConfigurationException("Tried to inherit, but failed to create a new instance of class: ${configClass.name}", e)
		}
		inheritFrom(config)
	}

	void inheritFrom(ContextConfig config) {
		ContextBuilder parentBuilder = new ContextBuilder()
		config.configure(parentBuilder)
		doInheritance(parentBuilder)
	}

	void inheritFrom(Closure config){
		ContextBuilder parentBuilder = new ContextBuilder()
		config.setDelegate(parentBuilder)
		config.call(parentBuilder)
		doInheritance(parentBuilder)
	}

	private void doInheritance(ContextBuilder parentBuilder) {
		Map parentBindings = parentBuilder.ctxBindings
		log.debug("Inheriting from ContextBuilder with class: ${parentBuilder.getClass().getName()} containing ${parentBindings.size()} bindings")
		parentBindings.putAll(ctxBindings) //Add this builders bindings to the parent's, overriding the parents' if there are any conflicts
		this.ctxBindings = parentBindings<commit_msg>added comments to ContextBuilder<commit_after>package net.ijus.nidi.builder

import groovy.transform.CompileStatic
import net.ijus.nidi.Configuration
import net.ijus.nidi.Context
import net.ijus.nidi.ContextConfig
import net.ijus.nidi.InvalidConfigurationException
import net.ijus.nidi.bindings.Scope
import org.slf4j.Logger
import org.slf4j.LoggerFactory

/**
 * Created by pfried on 7/2/14.
 */

@CompileStatic
public class ContextBuilder {
	static final Logger log = LoggerFactory.getLogger(ContextBuilder)

	boolean defaultScopeChanged = false

	Scope defaultScope = Scope.ALWAYS_CREATE_NEW
	Map<Class, BindingBuilder> ctxBindings = [:]

	protected Context ctx = new Context()

	/**
	 * alias for newBinding()
	 * @param clazz
	 * @return
	 */
	BindingBuilder bind(Class clazz){
		return newBinding(clazz)
	}

	/**
	 * Creates a new BindingBuilder for this class, with this ContextBuilder as it's parent.
	 * @param clazz the base class for this binding, typically an Interface or Abstract Class
	 * @return a new BindingBuilder, ready to be configured.
	 */
	BindingBuilder newBinding(Class clazz){
		BindingBuilder bb = new BindingBuilder(clazz, this)
		ctxBindings.put(clazz, bb)
		bb
	}

	/**
	 * Sets the default scope for this contextBuilder. All bindings will inherit this scope, unless one is
	 * explicitly set on it.
	 * @param newScope
	 */
	void setDefaultScope(Scope newScope) {
		this.defaultScope = newScope
		this.defaultScopeChanged = true
	}

	/**
	 * {@see #inheritFrom(ContextConfig)}
	 * @param fqcn fully-qualified class name of the ContextConfig class
	 */
	void inheritFrom(String fqcn){
		Class configClass
		try {
			configClass = Class.forName(fqcn)
		} catch (ClassNotFoundException e) {
			throw new InvalidConfigurationException("Tried to inherit from: ${fqcn}, but the class could not be found", e)
		}
		inheritFrom(configClass)
	}

	/**
	 * {@see #inheritFrom(ContextConfig)}
	 * @param configClass a class that implements ContextConfig, which will be created by simply calling newInstance() on it
	 */
	void inheritFrom(Class configClass) {
		if (!ContextConfig.isAssignableFrom(configClass)) {
			throw new InvalidConfigurationException("Tried to inherit from: ${configClass.name}, but that class does not immplement ContextConfig")
		}
		ContextConfig config
		try {
			config = configClass.newInstance() as ContextConfig
		} catch (InstantiationException | IllegalAccessException e) {
			throw new InvalidConfigurationException("Tried to inherit, but failed to create a new instance of class: ${configClass.name}", e)
		}
		inheritFrom(config)
	}

	/**
	 * Inherits from another ContextConfig. Allows for having a default ContextConfig and allows other Contexts to inherit
	 * from it and override only the functionality they need to.
	 * @param config
	 */
	void inheritFrom(ContextConfig config) {
		ContextBuilder parentBuilder = new ContextBuilder()
		config.configure(parentBuilder)
		doInheritance(parentBuilder)
	}

	/**
	 * {@see #inheritFrom(ContextConfig)}
	 * @param config closure that configures a contextBuilder
	 */
	void inheritFrom(Closure config){
		ContextBuilder parentBuilder = new ContextBuilder()
		config.setDelegate(parentBuilder)
		config.call(parentBuilder)
		doInheritance(parentBuilder)
	}

	/**
	 * Consumes the parent context builder and adds it's bindings to this builder. Always preserves the bindings from this
	 * builder if there is a conflict.
	 * Don't call this method directly, and the parentBuilder is expected to be a throw-away created only for the purpose
	 * of inheriting it's bindings.
	 * @param parentBuilder
	 */
	private void doInheritance(ContextBuilder parentBuilder) {
		Map parentBindings = parentBuilder.ctxBindings
		log.debug("Inheriting from ContextBuilder with class: ${parentBuilder.getClass().getName()} containing ${parentBindings.size()} bindings")
		parentBindings.putAll(ctxBindings) //Add this builders bindings to the parent's, overriding the parents' if there are any conflicts
		this.ctxBindings = parentBindings
{'fraction_non_alphanumeric': 0.08344838165362786, 'fraction_numerical': 0.0018407731247123793, 'mean_word_length': 4.92188919164396, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '6741640', 'n_tokens_mistral': 1978, 'n_tokens_neox': 1799, 'n_words': 567}