<commit_before>package net.ayld.facade.model;

import java.util.regex.Pattern;

import net.ayld.facade.util.Tokenizer;

/** 
 * Meant to represent a fully qualified class name.
 * 
 * The idea behind the class is to provide a model object that makes sure that a string is actually a class name and not 
 * something else, so one doesn't need to check 'by hand' every time.
 * */
public final class ClassName {

	/** 
	 * This regex only checks plausibility it doesn't check validity. For a validity check a comparison against Java's reserved words must be made.
	 * Also checks whether the name contains only Unicode chars.
	 * 
	 * More info here:
	 *   http://docs.oracle.com/javase/specs/#3.8
	 * 
	 * */
	private final static String CLASS_NAME_VALIDATION_REGEX = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)*[a-zA-Z_$][a-zA-Z\\d_$]*";
	
	private final String qualifiedClassName;

	/** 
	 * Creates a {@link ClassName}.
	 * 
	 * Doesn't allow nulls or empty strings.
	 * Does everything it can to make sure that the argument is in fact a fully qualified class name and not something else.
	 * 
	 * @param qualifiedClassName a class name
	 * 
	 * @return a new {@link ClassName}
	 * */
	public ClassName(String qualifiedClassName) {
		if (!isClassName(qualifiedClassName)) {
			throw new IllegalArgumentException("invalid fully qualified class name: " + qualifiedClassName + ", expected: " + CLASS_NAME_VALIDATION_REGEX);
		}
		this.qualifiedClassName = qualifiedClassName;
	}

	private static boolean isClassName(String qualifiedClassName) {
		return Pattern.matches(CLASS_NAME_VALIDATION_REGEX, qualifiedClassName);
	}

	/** 
	 * Returns the short name of the wrapped qualified class name.
	 * 
	 * In other words for this:
	 *   
	 *   <code>net.ayld.facade.model.ClassName</code>
	 * <commit_msg>fixed bug:  - package-info.class was not allowed by the ClassName validations although it was a valid class<commit_after>package net.ayld.facade.model;

import java.util.Set;
import java.util.regex.Pattern;

import com.google.common.collect.ImmutableSet;

import net.ayld.facade.util.Tokenizer;

/** 
 * Meant to represent a fully qualified class name.
 * 
 * The idea behind the class is to provide a model object that makes sure that a string is actually a class name and not 
 * something else, so one doesn't need to check 'by hand' every time.
 * */
public final class ClassName {

	/** 
	 * This regex only checks plausibility it doesn't check validity. For a validity check a comparison against Java's reserved words must be made.
	 * Also checks whether the name contains only Unicode chars.
	 * 
	 * More info here:
	 *   http://docs.oracle.com/javase/specs/#3.8
	 * 
	 * */
	private final static String CLASS_NAME_VALIDATION_REGEX = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)*[a-zA-Z_$][a-zA-Z\\d_$]*";
	
	
	/** 
	 * Class names that are valid classes, but still don't match the above regex.
	 * 
	 * See here:
	 *     http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#packagecomment
	 * */
	private final static Set<String> EXCEPTIONAL_CLASS_NAMES = ImmutableSet.of(
			"package-info"
	);
	
	private final String qualifiedClassName;

	/** 
	 * Creates a {@link ClassName}.
	 * 
	 * Doesn't allow nulls or empty strings.
	 * Does everything it can to make sure that the argument is in fact a fully qualified class name and not something else.
	 * 
	 * @param qualifiedClassName a class name
	 * 
	 * @return a new {@link ClassName}
	 * */
	public ClassName(String qualifiedClassName) {
		if (!isClassName(qualifiedClassName)) {
			throw new IllegalArgumentException("invalid fully qualified class name: " + qualifiedClassName + ", expected: " + CLASS_NAME_VALIDATION_REGEX);
		}
		this.qualifiedClassName = qualifiedClassName;
	}

	private static boolean isClassName(String qualifiedClassName) {
		return Pattern.matches(CLASS_NAME_VALIDATION_REGEX, qualifiedClassName) || EXCEPTIONAL_CLASS_NAMES.contains(qualifiedClassName);
	}

	/** 
	 * Returns the short name of the wrapped qualified class name.
	 * 
	 * In other words for this:
	 *   
	 *   <code>net.ayld.facade.model.ClassName</code>
	 * 
{'fraction_non_alphanumeric': 0.10104699293888483, 'fraction_numerical': 0.0012174336498660824, 'mean_word_length': 3.6788154897494305, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, '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': '4817669', 'n_tokens_mistral': 1306, 'n_tokens_neox': 1156, 'n_words': 407}