<commit_before>/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.gen5.api.extension;

import static org.junit.gen5.commons.meta.API.Usage.Experimental;

import java.lang.reflect.AnnotatedElement;
import java.util.*;
import java.util.function.Function;

import org.junit.gen5.commons.meta.API;
import org.junit.gen5.commons.util.Preconditions;

/**
 * {@code ExtensionContext} encapsulates the <em>context</em> in which the
 * current test or container is being executed.
 *
 * <p>{@link Extension Extensions} are provided an instance of
 * {@code ExtensionContext} to perform their work.
 *
 * @since 5.0
 */
@API(Experimental)
public interface ExtensionContext {

	/**
	 * Get the parent extension context if there is one.
	 */
	Optional<ExtensionContext> getParent();

	/**
	 * Get the unique id of the current test or container.
	 */
	String getUniqueId();

	/**
	 * Get the name for the current test or container.
	 *
	 * <p>The <em>name</em> is typically a technical name of the underlying
	 * artifact &mdash; for example, the fully qualified name of a Java class,
	 * the canonical absolute path to a file in the file system, etc.
	 *
	 * @see #getDisplayName()
	 */
	String getName();

	/**
	 * Get the display name for the current test or container.
	 *
	 * <p>Display names are typically used for test reporting in IDEs and
	 * build tools and may contain spaces, special characters, and even emoji.
	 */
	String getDisplayName();

	/**
	 * Get the set of all tags. Might be declared directly on this element
	 * or "inherited" from an outer context.
	 */
	Set<String> getTags();

	/**
	 * Get the {@link Class} associated with the current test or container.
	 */
	Class<?> getTestClass();

	/**
	 * Get the {@link AnnotatedElement} corresponding to the current extension
	 * context.
	 *
	 * <p>For example, if the current extension context encapsulates a test
	 * class or test method, the annotated element will be the corresponding
	 * {@link #getTestClass() Class} or {@link java.lang.reflect.Method Method}
	 * reference.
	 *
	 * <p>Favor this method over more specific methods whenever the
	 * {@link AnnotatedElement} API suits the task at hand (e.g., when
	 * looking up annotations regardless of concrete element type).
	 *
	 * @see #getTestClass()
	 */
	AnnotatedElement getElement();

	/**
	 * Publish a map of values to be consumed by an
	 * {@code org.junit.gen5.engine.EngineExecutionListener}.
	 *
	 * @param values the map of values to be reported for this entry
	 */
	void publishReportEntry(Map<String, String> values);

	/**
	 * Get a {@link Store} with the default {@link Namespace}.
	 *
	 * @see #getStore(Namespace)
	 */
	default Store getStore() {
		return getStore(Namespace.DEFAULT);
	}

	/**
	 * Get a {@link Store} for a self constructed {@link Namespace}.
	 *
	 * @return the store in which to put and get objects for other invocations
	 * of the same extension or different ones
	 */
	Store getStore(Namespace namespace);

	/**
	 * {@code Store} provides methods for extensions to save and retrieve data.
	 */
	interface Store {

		/**
		 * Get an object that has been stored using a {@code key}.
		 *
		 * <p>If no value has been saved in the current {@link ExtensionContext} for this {@code key},
		 * the ancestors are asked for a value with the same {@code key} in the store's {@code Namespace}.
		 *
		 * @param key the key
		 * @return the value
		 */
		Object get(Object key);

		/**
		 * Store a {@code value} for later retrieval using a {@code key}. {@code null} is a valid value.
		 *
		 * <p>A stored {@code value} is visible in offspring {@link ExtensionContext}s
		 * for the store's {@code Namespace} unless they overwrite it.
		 *
		 * @param key the key
		 * @param value the value
		 */
		void put(Object key, Object value);

		/**
		 * Get the object that is stored under the supplied {@code key}.
		 *
		 * <p>If no value is currently stored under the supplied {@code key},
		 * a new value will be computed by the {@code defaultCreator}, stored,
		 * and returned.
		 *
		 * @param key the key
		 * @param defaultCreator the function called to create new values
		 * @return the value
		 */
		Object getOrComputeIfAbsent(Object key, Function<Object, Object> defaultCreator);

		/**
		 * Remove a value that was previously stored using {@code key} so that {@code key} can be used anew.
		 *
		 * <p>The key will only be removed in the current {@link ExtensionContext} not in ancestors.
		 *
		 * @param key the key
		 * @return the previous value or {@code null} if no value was present
		 * for the specified key
		 */
		Object remove(Object key);
	}

	/**
	 * Instances of this class are used to give saved data in extensions a scope, so that
	 * extensions won't accidentally mix up data across each other or across different invocations
	 * within their lifecycle.
	 */
	class Namespace {

		/**
		 * The default namespace which allows access to stored data from all extensions.
		 */
		public static final Namespace DEFAULT = Namespace.of(new Object());

		/**
		 * Create a namespace which restricts access to data to all users which use the same
		 * {@code parts} for creating a namespace. The order of the  {@code parts} is not significant.
		 *
		 * <p>Internally the {@code parts} are compared using {@code Object.equals(Object)}.
		 */
		public static Namespace of(Object... parts) {
			Preconditions.notNull(parts, "There must be at least one reference object to create a namespace");

			return new Namespace(parts);
		}

		private final Set<?> parts;

		private Namespace(Object... parts) {
			this.parts = new HashSet<>(Arrays.asList(parts));
		}

		@Override
		public boolean equals(Object o) {
			if (this == o)
				return true;
			if (o == null || getClass() != o.getClass())
				return false;
			Namespace namespace = (Namespace) o;
			return parts.equals(namespace.parts);
		}

		@Override
		public int hashCode() {
			return parts.hashCode();
		}
	}

}
<commit_msg>Improve comment on 'ExtensionContext.Store::getOrComputeIfAbsent'<commit_after>/*
 * Copyright 2015-2016 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution and is available at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.junit.gen5.api.extension;

import static org.junit.gen5.commons.meta.API.Usage.Experimental;

import java.lang.reflect.AnnotatedElement;
import java.util.*;
import java.util.function.Function;

import org.junit.gen5.commons.meta.API;
import org.junit.gen5.commons.util.Preconditions;

/**
 * {@code ExtensionContext} encapsulates the <em>context</em> in which the
 * current test or container is being executed.
 *
 * <p>{@link Extension Extensions} are provided an instance of
 * {@code ExtensionContext} to perform their work.
 *
 * @since 5.0
 */
@API(Experimental)
public interface ExtensionContext {

	/**
	 * Get the parent extension context if there is one.
	 */
	Optional<ExtensionContext> getParent();

	/**
	 * Get the unique id of the current test or container.
	 */
	String getUniqueId();

	/**
	 * Get the name for the current test or container.
	 *
	 * <p>The <em>name</em> is typically a technical name of the underlying
	 * artifact &mdash; for example, the fully qualified name of a Java class,
	 * the canonical absolute path to a file in the file system, etc.
	 *
	 * @see #getDisplayName()
	 */
	String getName();

	/**
	 * Get the display name for the current test or container.
	 *
	 * <p>Display names are typically used for test reporting in IDEs and
	 * build tools and may contain spaces, special characters, and even emoji.
	 */
	String getDisplayName();

	/**
	 * Get the set of all tags. Might be declared directly on this element
	 * or "inherited" from an outer context.
	 */
	Set<String> getTags();

	/**
	 * Get the {@link Class} associated with the current test or container.
	 */
	Class<?> getTestClass();

	/**
	 * Get the {@link AnnotatedElement} corresponding to the current extension
	 * context.
	 *
	 * <p>For example, if the current extension context encapsulates a test
	 * class or test method, the annotated element will be the corresponding
	 * {@link #getTestClass() Class} or {@link java.lang.reflect.Method Method}
	 * reference.
	 *
	 * <p>Favor this method over more specific methods whenever the
	 * {@link AnnotatedElement} API suits the task at hand (e.g., when
	 * looking up annotations regardless of concrete element type).
	 *
	 * @see #getTestClass()
	 */
	AnnotatedElement getElement();

	/**
	 * Publish a map of values to be consumed by an
	 * {@code org.junit.gen5.engine.EngineExecutionListener}.
	 *
	 * @param values the map of values to be reported for this entry
	 */
	void publishReportEntry(Map<String, String> values);

	/**
	 * Get a {@link Store} with the default {@link Namespace}.
	 *
	 * @see #getStore(Namespace)
	 */
	default Store getStore() {
		return getStore(Namespace.DEFAULT);
	}

	/**
	 * Get a {@link Store} for a self constructed {@link Namespace}.
	 *
	 * @return the store in which to put and get objects for other invocations
	 * of the same extension or different ones
	 */
	Store getStore(Namespace namespace);

	/**
	 * {@code Store} provides methods for extensions to save and retrieve data.
	 */
	interface Store {

		/**
		 * Get an object that has been stored using a {@code key}.
		 *
		 * <p>If no value has been saved in the current {@link ExtensionContext} for this {@code key},
		 * the ancestors are asked for a value with the same {@code key} in the store's {@code Namespace}.
		 *
		 * @param key the key
		 * @return the value
		 */
		Object get(Object key);

		/**
		 * Store a {@code value} for later retrieval using a {@code key}. {@code null} is a valid value.
		 *
		 * <p>A stored {@code value} is visible in offspring {@link ExtensionContext}s
		 * for the store's {@code Namespace} unless they overwrite it.
		 *
		 * @param key the key
		 * @param value the value
		 */
		void put(Object key, Object value);

		/**
		 * Get the object that is stored under the supplied {@code key}.
		 *
		 * <p>If no value is currently stored under the supplied {@code key},
		 * a new value will be computed by the {@code defaultCreator} (given
		 * the {@code key} as input parameter), stored, and returned.
		 *
		 * @param key the key
		 * @param defaultCreator the function called with the supplied {@code key} to create new values
		 * @return the value
		 */
		Object getOrComputeIfAbsent(Object key, Function<Object, Object> defaultCreator);

		/**
		 * Remove a value that was previously stored using {@code key} so that {@code key} can be used anew.
		 *
		 * <p>The key will only be removed in the current {@link ExtensionContext} not in ancestors.
		 *
		 * @param key the key
		 * @return the previous value or {@code null} if no value was present
		 * for the specified key
		 */
		Object remove(Object key);
	}

	/**
	 * Instances of this class are used to give saved data in extensions a scope, so that
	 * extensions won't accidentally mix up data across each other or across different invocations
	 * within their lifecycle.
	 */
	class Namespace {

		/**
		 * The default namespace which allows access to stored data from all extensions.
		 */
		public static final Namespace DEFAULT = Namespace.of(new Object());

		/**
		 * Create a namespace which restricts access to data to all users which use the same
		 * {@code parts} for creating a namespace. The order of the  {@code parts} is not significant.
		 *
		 * <p>Internally the {@code parts} are compared using {@code Object.equals(Object)}.
		 */
		public static Namespace of(Object... parts) {
			Preconditions.notNull(parts, "There must be at least one reference object to create a namespace");

			return new Namespace(parts);
		}

		private final Set<?> parts;

		private Namespace(Object... parts) {
			this.parts = new HashSet<>(Arrays.asList(parts));
		}

		@Override
		public boolean equals(Object o) {
			if (this == o)
				return true;
			if (o == null || getClass() != o.getClass())
				return false;
			Namespace namespace = (Namespace) o;
			return parts.equals(namespace.parts);
		}

		@Override
		public int hashCode() {
			return parts.hashCode();
		}
	}

}

{'fraction_non_alphanumeric': 0.10197917494634767, 'fraction_numerical': 0.003020427628964311, 'mean_word_length': 3.3611785095320625, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5327771', 'n_tokens_mistral': 3831, 'n_tokens_neox': 3379, 'n_words': 1519}