<commit_before>/*
 *  Copyright (c) 2012-2017, <NAME> 
 *			
 *  Licensed under the Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
 */
package se.jbee.inject;

import static se.jbee.inject.Packages.packageAndSubPackagesOf;
import static se.jbee.inject.Packages.packageOf;
import static se.jbee.inject.Packages.subPackagesOf;
import static se.jbee.inject.Type.raw;

/**
 * Describes where a {@link Resource} is available for injection.
 * 
 * This can be restricted by the {@link Packages} the injected that is injected is defined in or the
 * {@link Type} of the receiving instance.
 * 
 * @author <NAME> (<EMAIL>)
 */
public final class Target
		implements MorePreciseThan<Target> {

	public static final Target ANY = targeting( Instance.ANY );

	public static Target targeting( Class<?> type ) {
		return targeting( raw( type ) );
	}

	public static Target targeting( Type<?> type ) {
		return targeting( Instance.anyOf( type ) );
	}

	public static Target targeting( Instance<?> instance ) {
		return new Target( Instances.ANY, instance, Packages.ALL );
	}

	public final Instances parents;
	public final Instance<?> instance;
	public final Packages packages;

	private Target( Instances parents, Instance<?> instance, Packages packages ) {
		super();
		this.parents = parents;
		this.instance = instance;
		this.packages = packages;
	}

	public Target within( Instance<?> parent ) {
		return new Target( parents.push( parent ), instance, packages );
	}

	public Target injectingInto( Instance<?> instance ) {
		return new Target( parents, instance, packages );
	}

	public Target in( Packages packages ) {
		return new Target( parents, instance, packages );
	}

	public Target injectingInto( Type<?> type ) {
		return injectingInto( Instance.anyOf( type ) );
	}

	public Target injectingInto( Class<?> type ) {
		return injectingInto( raw( type ) );
	}

	public boolean isAvailableFor( Dependency<?> dependency ) {
		return isAccessibleFor( dependency ) && isCompatibleWith( dependency );
	}

	/**
	 * @return true in case the actual types of the injection hierarchy are
	 *         assignable with the ones demanded by this target.
	 */
	public boolean isCompatibleWith( Dependency<?> dependency ) {
		if ( !areParentsCompatibleWith( dependency ) ) {
			return false;
		}
		if ( instance.isAny() ) {
			return true;
		}
		final Instance<?> target = dependency.target();
		return instance.name.isCompatibleWith( target.name )
				&& isAssingableTo( instance.type(), target.type() );
	}

	private boolean areParentsCompatibleWith( Dependency<?> dependency ) {
		if ( parents.isAny() ) {
			return true;
		}
		int pl = parents.depth();
		int il = dependency.injectionDepth() - 1;
		if ( pl > il ) {
			return false;
		}
		int pi = 0;
		while ( pl <= il && pl > 0 ) {
			if ( isAssingableTo( parents.at( pi ).type(), dependency.target( il ).type() ) ) {
				pl--;
				pi++;
			}
			il--;
		}
		return pl == 0;
	}

	private static boolean isAssingableTo( Type<?> type, Type<?> targetType ) {
		return type.isInterface() || type.isAbstract()
			? targetType.isAssignableTo( type )
			: targetType.equalTo( type );
	}

	public boolean isAccessibleFor( Dependency<?> dependency ) {
		return packages.contains( dependency.target().type() );
	}

	@Override
	public String toString() {
		String res = "[";
		res += parents.toString() + " ";
		res += instance.isAny()
			? "anything"
			: instance.toString();
		res += " ";
		res += packages.includesAll()
			? "anywhere"
			: packages.toString();
		return res + "]";
	}

	public Target inPackageAndSubPackagesOf( Class<?> type ) {
		return in( packageAndSubPackagesOf( type ) );
	}

	public Target inPackageOf( Class<?> type ) {
		return in( packageOf( type ) );
	}

	public Target inSubPackagesOf( Class<?> type ) {
		return in( subPackagesOf( type ) );
	}

	@Override
	public boolean morePreciseThan( Target other ) {
		final int ol = other.parents.depth();
		final int l = parents.depth();
		if ( ol != l ) {
			return l > ol;
		}
		if ( l > 0 ) { // length is known to be equal
			if ( parents.morePreciseThan( other.parents ) ) {
				return true;
			}
			if ( other.parents.morePreciseThan( parents ) ) {
				return false;<commit_msg>minor change to test travis CI<commit_after>/*
 *  Copyright (c) 2012-2017, <NAME> 
 *			
 *  Licensed under the Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
 */
package se.jbee.inject;

import static se.jbee.inject.Packages.packageAndSubPackagesOf;
import static se.jbee.inject.Packages.packageOf;
import static se.jbee.inject.Packages.subPackagesOf;
import static se.jbee.inject.Type.raw;

/**
 * Describes where a {@link Resource} is available for injection.
 * 
 * This can be restricted by the {@link Packages} the injected that is injected is defined in or the
 * {@link Type} of the receiving instance.
 * 
 * @author <NAME> (<EMAIL>)
 */
public final class Target
		implements MorePreciseThan<Target> {

	public static final Target ANY = targeting( Instance.ANY );

	public static Target targeting( Class<?> type ) {
		return targeting( raw( type ) );
	}

	public static Target targeting( Type<?> type ) {
		return targeting( Instance.anyOf( type ) );
	}

	public static Target targeting( Instance<?> instance ) {
		return new Target( Instances.ANY, instance, Packages.ALL );
	}

	public final Instances parents;
	public final Instance<?> instance;
	public final Packages packages;

	private Target( Instances parents, Instance<?> instance, Packages packages ) {
		super();
		this.parents = parents;
		this.instance = instance;
		this.packages = packages;
	}

	public Target within( Instance<?> parent ) {
		return new Target( parents.push( parent ), instance, packages );
	}

	public Target injectingInto( Instance<?> instance ) {
		return new Target( parents, instance, packages );
	}

	public Target in( Packages packages ) {
		return new Target( parents, instance, packages );
	}

	public Target injectingInto( Type<?> type ) {
		return injectingInto( Instance.anyOf( type ) );
	}

	public Target injectingInto( Class<?> type ) {
		return injectingInto( raw( type ) );
	}

	public boolean isAvailableFor( Dependency<?> dependency ) {
		return isAccessibleFor( dependency ) && isCompatibleWith( dependency );
	}

	/**
	 * @return true in case the actual types of the injection hierarchy are
	 *         assignable with the ones demanded by this target.
	 */
	public boolean isCompatibleWith( Dependency<?> dependency ) {
		if ( !areParentsCompatibleWith( dependency ) ) {
			return false;
		}
		if ( instance.isAny() ) {
			return true;
		}
		final Instance<?> target = dependency.target();
		return instance.name.isCompatibleWith( target.name )
				&& isAssingableTo( instance.type(), target.type() );
	}

	private boolean areParentsCompatibleWith( Dependency<?> dependency ) {
		if ( parents.isAny() ) {
			return true;
		}
		int pl = parents.depth();
		int il = dependency.injectionDepth() - 1;
		if ( pl > il ) {
			return false;
		}
		int pi = 0;
		while ( pl <= il && pl > 0 ) {
			if ( isAssingableTo( parents.at( pi ).type(), dependency.target( il ).type() ) ) {
				pl--;
				pi++;
			}
			il--;
		}
		return pl == 0;
	}

	private static boolean isAssingableTo( Type<?> type, Type<?> targetType ) {
		return type.isInterface() || type.isAbstract()
			? targetType.isAssignableTo( type )
			: targetType.equalTo( type );
	}

	public boolean isAccessibleFor( Dependency<?> dependency ) {
		return packages.contains( dependency.target().type() );
	}

	@Override
	public String toString() {
		String res = "[";
		res += parents.toString() + " ";
		res += instance.isAny()
			? "anything"
			: instance.toString();
		res += " ";
		res += packages.includesAll()
			? "anywhere"
			: packages.toString();
		return res + "]";
	}

	public Target inPackageAndSubPackagesOf( Class<?> type ) {
		return in( packageAndSubPackagesOf( type ) );
	}

	public Target inPackageOf( Class<?> type ) {
		return in( packageOf( type ) );
	}

	public Target inSubPackagesOf( Class<?> type ) {
		return in( subPackagesOf( type ) );
	}

	@Override
	public boolean morePreciseThan( Target other ) {
		final int ol = other.parents.depth();
		final int l = parents.depth();
		if ( ol != l )
			return l > ol;
		if ( l > 0 ) { // length is known to be equal
			if ( parents.morePreciseThan( other.parents ) ) {
				return true;
			}
			if ( other.parents.morePreciseThan( parents ) ) {
				return false;
{'fraction_non_alphanumeric': 0.12839681974605435, 'fraction_numerical': 0.004034650528064555, 'mean_word_length': 3.5606060606060606, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 57, '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': '4993681', 'n_tokens_mistral': 2842, 'n_tokens_neox': 2577, 'n_words': 788}