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);
}