* if true, every {@link XmlElementRef} must yield at least one type.
*/
private void calcTypes(boolean last) {
XmlElementRef[] ann;
types = new LinkedHashSet<Element<T,C>>();
XmlElementRefs refs = seed.readAnnotation(XmlElementRefs.class);
XmlElementRef ref = seed.readAnnotation(XmlElementRef.class);
if(refs!=null && ref!=null) {
parent.builder.reportError(new IllegalAnnotationException(
Messages.MUTUALLY_EXCLUSIVE_ANNOTATIONS.format(
nav().getClassName(parent.getClazz())+'#'+seed.getName(),
ref.annotationType().getName(), refs.annotationType().getName()),
ref, refs ));
}
if(refs!=null)
ann = refs.value();
else {
if(ref!=null)
ann = new XmlElementRef[]{ref};
else
ann = null;
}
isRequired = !isCollection(); // this is by default, to remain compatible with 2.1
if(ann!=null) {
Navigator<T,C,F,M> nav = nav();
AnnotationReader<T,C,F,M> reader = reader();
final T defaultType = nav.ref(XmlElementRef.DEFAULT.class);
final C je = nav.asDecl(JAXBElement.class);
for( XmlElementRef r : ann ) {
boolean yield;
T type = reader.getClassValue(r,"type");
if( type.equals(defaultType) ) type = nav.erasure(getIndividualType());
if(nav.getBaseClass(type,je)!=null)
yield = addGenericElement(r);
else
yield = addAllSubtypes(type);
// essentially "isRequired &= isRequired(r)" except that we'd like to skip evaluating isRequird(r)
// if the value is already false.
if(isRequired && !isRequired(r))
isRequired = false;
if(last && !yield) {
// a reference didn't produce any type.
// diagnose the problem
if(type.equals(nav.ref(JAXBElement.class))) {
// no XmlElementDecl
parent.builder.reportError(new IllegalAnnotationException(
Messages.NO_XML_ELEMENT_DECL.format(
getEffectiveNamespaceFor(r), r.name()),
this
));
} else {
parent.builder.reportError(new IllegalAnnotationException(
Messages.INVALID_XML_ELEMENT_REF.format(type),this));
}
// reporting one error would do.
// often the element ref field is using @XmlElementRefs
// to point to multiple JAXBElements.
// reporting one error for each @XmlElemetnRef is thus often redundant.
return;
}
}
}
Iterator<PropertyInfoImpl<T,C,F,M>> i = subTypes.iterator();
while (i.hasNext()) {
ReferencePropertyInfoImpl<T,C,F,M> info = (ReferencePropertyInfoImpl<T, C, F, M>) i.next();
PropertySeed sd = info.seed;
refs = sd.readAnnotation(XmlElementRefs.class);
ref = sd.readAnnotation(XmlElementRef.class);
if (refs != null && ref != null) {
parent.builder.reportError(new IllegalAnnotationException(
Messages.MUTUALLY_EXCLUSIVE_ANNOTATIONS.format(
nav().getClassName(parent.getClazz())+'#'+seed.getName(),
ref.annotationType().getName(), refs.annotationType().getName()),
ref, refs ));
}
if (refs != null) {
ann = refs.value();
} else {
if (ref != null) {
ann = new XmlElementRef[]{ref};
} else {
ann = null;