private void calculateServiceType()

in cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ReferenceModel.java [327:560]


	private void calculateServiceType(Type type) {
		if (!(type instanceof ParameterizedType)) {
			if (!(type instanceof Class)) {
				throw new IllegalArgumentException(
					"The service type must not be generic: " + type + " on " + _annotated);
			}

			Class<?> clazz = cast(type);

			if (Map.class == clazz) {
				throw new IllegalArgumentException(
					"Map must specify a generic type arguments: " + clazz);
			}
			else if (Map.Entry.class == clazz) {
				throw new IllegalArgumentException(
					"Map.Entry must specify a generic type arguments: " + clazz);
			}
			else if ((BeanServiceObjects.class == clazz) && !_referenceType.isPresent()) {
				throw new IllegalArgumentException(
					"ReferenceServiceObjects must specify a generic type argument: " + clazz);
			}
			else if ((ServiceReference.class == clazz) && !_referenceType.isPresent()) {
				throw new IllegalArgumentException(
					"ServiceReference must specify a generic type argument: " + type);
			}
			else if ((Collection.class == clazz || List.class == clazz) &&
					!_referenceType.isPresent()) {

				throw new IllegalArgumentException(
					type + " must specify a generic type argument");
			}
			else if (BeanServiceObjects.class == clazz) {
				_collectionType = CollectionType.SERVICEOBJECTS;
				return;
			}
			else if (ServiceReference.class == clazz) {
				_collectionType = CollectionType.REFERENCE;
				return;
			}
			else if (Collection.class == clazz || List.class == clazz) {
				_collectionType = CollectionType.SERVICE;
				_multiplicity = MaximumCardinality.MANY;
				_optional = true;
				return;
			}

			_serviceType = clazz;

			return;
		}

		ParameterizedType parameterizedType = cast(type);

		Type rawType = parameterizedType.getRawType();

		Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();

		Type argument = actualTypeArguments[0];

		if (Instance.class == cast(rawType)) {
			throw new IllegalArgumentException(
				"Instance<T> is not supported with @Reference: " + type);
		}

		if (BindService.class.isAssignableFrom(cast(rawType))) {
			_collectionType = CollectionType.BINDER_SERVICE;
			_dynamic = true;
			_multiplicity = MaximumCardinality.MANY;
			_optional = true;

			if (argument instanceof WildcardType ||
				argument instanceof ParameterizedType) {

				throw new IllegalArgumentException(
					"Type argument <S> of BindObject must not be generic: " + argument);
			}

			_serviceType = cast(argument);

			return;
		}

		if (BindServiceReference.class.isAssignableFrom(cast(rawType))) {
			_collectionType = CollectionType.BINDER_REFERENCE;
			_dynamic = true;
			_multiplicity = MaximumCardinality.MANY;
			_optional = true;

			if (argument instanceof WildcardType ||
				argument instanceof ParameterizedType) {

				throw new IllegalArgumentException(
					"Type argument <S> of BindServiceReference must not be generic: " + argument);
			}

			_serviceType = cast(argument);

			return;
		}

		if (BindBeanServiceObjects.class.isAssignableFrom(cast(rawType))) {
			_collectionType = CollectionType.BINDER_BEAN_SERVICE_OBJECTS;
			_dynamic = true;
			_multiplicity = MaximumCardinality.MANY;
			_optional = true;

			if (argument instanceof WildcardType ||
				argument instanceof ParameterizedType) {

				throw new IllegalArgumentException(
					"Type argument <S> of BindServiceObjects must not be generic: " + argument);
			}

			_serviceType = cast(argument);

			return;
		}

		if ((!_dynamic) && (Provider.class == cast(rawType))) {
			_dynamic = true;

			calculateServiceType(argument);

			return;
		}

		if ((!_optional) && (Optional.class == cast(rawType))) {
			_optional = true;

			if ((argument instanceof WildcardType) && _referenceType.isPresent()) {
				return;
			}

			calculateServiceType(argument);

			return;
		}

		if ((_multiplicity == MaximumCardinality.ONE) &&
			((Collection.class == cast(rawType)) ||
			(List.class == cast(rawType)))) {

			_optional = true;
			_multiplicity = MaximumCardinality.MANY;

			if ((argument instanceof WildcardType) && _referenceType.isPresent()) {
				return;
			}

			calculateServiceType(argument);

			return;
		}

		if (Map.class == cast(rawType)) {
			if (String.class != cast(argument)) {
				throw new IllegalArgumentException(
					"Maps of properties must use the form Map<String, (? | Object)>: " + type);
			}

			argument = actualTypeArguments[1];

			if ((Object.class != cast(argument)) &&
				(!(argument instanceof WildcardType))) {

				throw new IllegalArgumentException(
					"Maps of properties must use the form Map<String, (? | Object)>: " + type);
			}

			_collectionType = CollectionType.PROPERTIES;

			if (!_referenceType.isPresent()) {
				throw new IllegalArgumentException(
					"Maps of properties must specify service type with @Reference.value(): " + argument + " on " + _annotated);
			}

			return;
		}

		if (Map.Entry.class == cast(rawType)) {
			if (!checkKey(argument)) {
				throw new IllegalArgumentException(
					"Tuples must have a key of type Map<String, (? | Object)>: " + argument + " on " + _annotated);
			}

			_collectionType = CollectionType.TUPLE;

			Type second = actualTypeArguments[1];

			if ((second instanceof WildcardType) && _referenceType.isPresent()) {
				return;
			}

			if (!(second instanceof Class)) {
				throw new IllegalArgumentException(
					"The service type must not be generic: " + second + " on " + _annotated);
			}

			_serviceType = cast(second);

			return;
		}

		if (BeanServiceObjects.class == cast(rawType)) {
			_collectionType = CollectionType.SERVICEOBJECTS;

			if ((argument instanceof WildcardType) && _referenceType.isPresent()) {
				return;
			}

			calculateServiceType(argument);

			return;
		}

		if (ServiceReference.class == cast(rawType)) {
			_collectionType = CollectionType.REFERENCE;

			if ((argument instanceof WildcardType) && _referenceType.isPresent()) {
				return;
			}

			calculateServiceType(argument);

			return;
		}

		_serviceType = cast(rawType);

		if (_serviceType.getTypeParameters().length > 0) {
			throw new IllegalArgumentException(
				"Illegal service type: " + argument + " on " + _annotated);
		}
	}