public T run()

in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreator.java [256:373]


	public T run() {

		if (impl != null)
			return impl;

		if (type == null)
			return null;

		Value<String> found = Value.empty();

		// Look for getInstance(Builder).
		if (builder != null) {
			MethodInfo m = type.getPublicMethod(
				x -> x.isStatic()
				&& x.isNotDeprecated()
				&& x.hasNumParams(1)
				&& x.getParam(0).canAccept(builder)
				&& x.hasReturnType(type)
				&& x.hasNoAnnotation(BeanIgnore.class)
				&& x.hasName("getInstance")
			);
			if (m != null)
				return m.invoke(null, builder);
		}

		// Look for getInstance().
		if (builder == null) {
			MethodInfo m = type.getPublicMethod(
				x -> x.isStatic()
				&& x.isNotDeprecated()
				&& x.hasNoParams()
				&& x.hasReturnType(type)
				&& x.hasNoAnnotation(BeanIgnore.class)
				&& x.hasName("getInstance")
			);
			if (m != null)
				return m.invoke(null);
		}

		if (builder == null) {
			// Look for static creator methods.

			Match<MethodInfo> match = new Match<>();

			// Look for static creator method.
			type.forEachPublicMethod(x -> isStaticCreateMethod(x), x -> {
				found.set("STATIC_CREATOR");
				if (hasAllParams(x))
					match.add(x);
			});

			if (match.isPresent())
				return match.get().invoke(null, getParams(match.get()));
		}

		if (type.isInterface()) {
			if (silent)
				return null;
			throw new ExecutableException("Could not instantiate class {0}: {1}.", type.getName(), "Class is an interface");
		}

		if (type.isAbstract()) {
			if (silent)
				return null;
			throw new ExecutableException("Could not instantiate class {0}: {1}.", type.getName(), "Class is abstract");
		}

		// Look for public constructor.
		Match<ConstructorInfo> constructorMatch = new Match<>();
		type.forEachPublicConstructor(x -> true, x -> {
			found.setIfEmpty("PUBLIC_CONSTRUCTOR");
			if (hasAllParams(x))
				constructorMatch.add(x);
		});

		// Look for protected constructor.
		if (! constructorMatch.isPresent()) {
			type.forEachDeclaredConstructor(ConstructorInfo::isProtected, x -> {
				found.setIfEmpty("PROTECTED_CONSTRUCTOR");
				if (hasAllParams(x))
					constructorMatch.add(x);
			});
		}

		// Execute.
		if (constructorMatch.isPresent())
			return constructorMatch.get().invoke(getParams(constructorMatch.get()));

		if (builder == null) {
			// Look for static-builder/protected-constructor pair.
			Value<T> value = Value.empty();
			type.forEachDeclaredConstructor(x -> x.hasNumParams(1) && x.isVisible(PROTECTED), x -> {
				Class<?> pt = x.getParam(0).getParameterType().inner();
				MethodInfo m = type.getPublicMethod(y -> isStaticCreateMethod(y, pt));
				if (m != null) {
					Object builder = m.invoke(null);
					value.set(x.accessible().invoke(builder));
				}
			});
			if (value.isPresent())
				return value.get();
		}

		if (silent)
			return null;

		String msg = null;
		if (found.isEmpty()) {
			msg = "No public/protected constructors found";
		} else if (found.get().equals("STATIC_CREATOR")) {
			msg = "Static creator found but could not find prerequisites: " + type.getPublicMethods().stream().filter(x -> isStaticCreateMethod(x)).map(x -> getMissingParams(x)).sorted().collect(joining(" or "));
		} else if (found.get().equals("PUBLIC_CONSTRUCTOR")) {
			msg = "Public constructor found but could not find prerequisites: " + type.getPublicConstructors().stream().map(x -> getMissingParams(x)).sorted().collect(joining(" or "));
		} else {
			msg = "Protected constructor found but could not find prerequisites: " + type.getDeclaredConstructors().stream().filter(ConstructorInfo::isProtected).map(x -> getMissingParams(x)).sorted().collect(joining(" or "));
		}
		throw new ExecutableException("Could not instantiate class {0}: {1}.", type.getName(), msg);
	}