in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java [171:310]
boolean validate(BeanContext bc, BeanRegistry parentBeanRegistry, Map<Class<?>,Class<?>[]> typeVarImpls, Set<String> bpro, Set<String> bpwo) throws Exception {
List<Class<?>> bdClasses = list();
if (field == null && getter == null && setter == null)
return false;
if (field == null && setter == null && bc.isBeansRequireSettersForGetters() && ! isConstructorArg)
return false;
canRead |= (field != null || getter != null);
canWrite |= (field != null || setter != null);
if (innerField != null) {
List<Beanp> lp = list();
bc.forEachAnnotation(Beanp.class, innerField, x -> true, x -> lp.add(x));
if (field != null || lp.size() > 0) {
// Only use field type if it's a bean property or has @Beanp annotation.
// Otherwise, we want to infer the type from the getter or setter.
rawTypeMeta = bc.resolveClassMeta(last(lp), innerField.getGenericType(), typeVarImpls);
isUri |= (rawTypeMeta.isUri());
}
lp.forEach(x -> {
if (! x.properties().isEmpty())
properties = split(x.properties());
addAll(bdClasses, x.dictionary());
if (! x.ro().isEmpty())
readOnly = Boolean.valueOf(x.ro());
if (! x.wo().isEmpty())
writeOnly = Boolean.valueOf(x.wo());
});
bc.forEachAnnotation(Swap.class, innerField, x -> true, x -> swap = getPropertySwap(x));
isUri |= bc.firstAnnotation(Uri.class, innerField, x->true) != null;
}
if (getter != null) {
List<Beanp> lp = list();
bc.forEachAnnotation(Beanp.class, getter, x -> true, x -> lp.add(x));
if (rawTypeMeta == null)
rawTypeMeta = bc.resolveClassMeta(last(lp), getter.getGenericReturnType(), typeVarImpls);
isUri |= (rawTypeMeta.isUri() || bc.hasAnnotation(Uri.class, getter));
lp.forEach(x -> {
if (properties != null && ! x.properties().isEmpty())
properties = split(x.properties());
addAll(bdClasses, x.dictionary());
if (! x.ro().isEmpty())
readOnly = Boolean.valueOf(x.ro());
if (! x.wo().isEmpty())
writeOnly = Boolean.valueOf(x.wo());
});
bc.forEachAnnotation(Swap.class, getter, x -> true, x -> swap = getPropertySwap(x));
}
if (setter != null) {
List<Beanp> lp = list();
bc.forEachAnnotation(Beanp.class, setter, x -> true, x -> lp.add(x));
if (rawTypeMeta == null)
rawTypeMeta = bc.resolveClassMeta(last(lp), setter.getGenericParameterTypes()[0], typeVarImpls);
isUri |= (rawTypeMeta.isUri() || bc.hasAnnotation(Uri.class, setter));
lp.forEach(x -> {
if (swap == null)
swap = getPropertySwap(x);
if (properties != null && ! x.properties().isEmpty())
properties = split(x.properties());
addAll(bdClasses, x.dictionary());
if (! x.ro().isEmpty())
readOnly = Boolean.valueOf(x.ro());
if (! x.wo().isEmpty())
writeOnly = Boolean.valueOf(x.wo());
});
bc.forEachAnnotation(Swap.class, setter, x -> true, x -> swap = getPropertySwap(x));
}
if (rawTypeMeta == null)
return false;
this.beanRegistry = new BeanRegistry(beanContext, parentBeanRegistry, bdClasses.toArray(new Class<?>[0]));
isDyna = "*".equals(name);
// Do some annotation validation.
ClassInfo ci = rawTypeMeta.getInfo();
if (getter != null) {
Class<?>[] pt = getter.getParameterTypes();
if (isDyna) {
if (ci.isChildOf(Map.class) && pt.length == 0) {
isDynaGetterMap = true;
} else if (pt.length == 1 && pt[0] == String.class) {
// OK.
} else {
return false;
}
} else {
if (! ci.isChildOf(getter.getReturnType()))
return false;
}
}
if (setter != null) {
Class<?>[] pt = setter.getParameterTypes();
if (isDyna) {
if (pt.length == 2 && pt[0] == String.class) {
// OK.
} else {
return false;
}
} else {
if (pt.length != 1 || ! ci.isChildOf(pt[0]))
return false;
}
}
if (field != null) {
if (isDyna) {
if (! ClassInfo.of(field.getType()).isChildOf(Map.class))
return false;
} else {
if (! ci.isChildOf(field.getType()))
return false;
}
}
if (isDyna) {
rawTypeMeta = rawTypeMeta.getValueType();
if (rawTypeMeta == null)
rawTypeMeta = beanContext.object();
}
if (rawTypeMeta == null)
return false;
if (typeMeta == null)
typeMeta = (swap != null ? beanContext.getClassMeta(swap.getSwapClass().innerType()) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta);
if (typeMeta == null)
typeMeta = rawTypeMeta;
if (bpro.contains(name) || bpro.contains("*"))
readOnly = true;
if (bpwo.contains(name) || bpwo.contains("*"))
writeOnly = true;
return true;
}