All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.jbee.inject.util.Argument Maven / Gradle / Ivy

There is a newer version: 0.6
Show newest version
/*
 *  Copyright (c) 2012, Jan Bernitt 
 *			
 *  Licensed under the Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
 */
package se.jbee.inject.util;

import static se.jbee.inject.Type.raw;
import se.jbee.inject.Dependency;
import se.jbee.inject.Injector;
import se.jbee.inject.Instance;
import se.jbee.inject.Parameter;
import se.jbee.inject.Type;

/**
 * A utility to supply {@link Parameter}s during the binding.
 * 
 * @author Jan Bernitt ([email protected])
 * 
 * @param 
 *            Type of value/argument
 */
public final class Argument
		implements Parameter {

	public static  Argument argumentFor( Parameter parameter ) {
		if ( parameter instanceof Argument ) {
			return (Argument) parameter;
		}
		if ( parameter instanceof Instance ) {
			return new Argument( (Instance) parameter );
		}
		if ( parameter instanceof Type ) {
			return new Argument( Instance.anyOf( (Type) parameter ) );
		}
		if ( parameter instanceof Dependency ) {
			return new Argument( (Dependency) parameter );
		}
		throw new IllegalArgumentException( "Unknown parameter type:" + parameter );
	}

	public static  Parameter constant( Class type, T constant ) {
		return constant( raw( type ), constant );
	}

	public static  Parameter constant( Type type, T constant ) {
		return new Argument( constant, type, null, null );
	}

	public static  Parameter asType( Class supertype, Parameter parameter ) {
		return asType( raw( supertype ), parameter );
	}

	public static  Parameter asType( Type supertype, Parameter parameter ) {
		Argument arg = argumentFor( parameter );
		return new Argument( arg.constant, supertype, arg.instance, arg.dependency );
	}

	public static boolean allConstants( Argument[] args ) {
		for ( Argument arg : args ) {
			if ( !arg.isConstant() ) {
				return false;
			}
		}
		return true;
	}

	public static Object[] constantsFrom( Argument[] args ) {
		Object[] consts = new Object[args.length];
		for ( int i = 0; i < args.length; i++ ) {
			consts[i] = args[i].constant;
		}
		return consts;
	}

	public static  Object[] resolve( Dependency dependency, Injector context,
			Argument[] arguments ) {
		Object[] args = new Object[arguments.length];
		for ( int i = 0; i < arguments.length; i++ ) {
			args[i] = arguments[i].resolve( dependency, context );
		}
		return args;
	}

	private final T constant;
	private final Type asType;
	private final Instance instance;
	private final Dependency dependency;

	private Argument( Instance instance ) {
		this( null, instance.getType(), instance, null );
	}

	private Argument( Dependency dependency ) {
		this( null, dependency.getType(), null, dependency );
	}

	private Argument( T constant, Type asType, Instance instance,
			Dependency dependency ) {
		super();
		this.constant = constant;
		this.asType = asType;
		this.instance = instance;
		this.dependency = dependency;
	}

	public T resolve( Dependency constructed, Injector context ) {
		if ( constant != null ) {
			return constant;
		}
		if ( dependency != null ) {
			return context.resolve( dependency );
		}
		return context.resolve( constructed.instanced( instance ) );
	}

	public boolean isConstant() {
		return constant != null;
	}

	@Override
	public boolean isAssignableTo( Type type ) {
		return asType.isAssignableTo( type );
	}

	@Override
	public String toString() {
		String as = " as " + asType.toString();
		if ( isConstant() ) {
			return constant.toString() + as;
		}
		if ( dependency != null ) {
			return dependency.toString() + as;
		}
		return instance.toString() + as;
	}

	public static Argument[] arguments( Type[] types, Parameter... parameters ) {
		Argument[] arguments = new Argument[types.length];
		for ( Parameter parameter : parameters ) {
			int i = 0;
			boolean found = false;
			while ( i < types.length && !found ) {
				if ( arguments[i] == null ) {
					found = parameter.isAssignableTo( types[i] );
					if ( found ) {
						arguments[i] = argumentFor( parameter );
					}
				}
				i++;
			}
			if ( !found ) {
				throw new IllegalArgumentException( "Couldn't understand parameter: " + parameter );
			}
		}
		for ( int i = 0; i < arguments.length; i++ ) {
			if ( arguments[i] == null ) {
				arguments[i] = argumentFor( types[i] );
			}
		}
		return arguments;
	}

}