Class<?> slotClazz;
SlotAccessData sad;
String propertyName;
Slot slotAnnotation;
Class aggregateType;
AggregateSlot aggregateSlotAnnotation;
boolean mandatory;
boolean manageAsSerializable;
int cardMin;
int cardMax;
String defaultValue;
String regex;
String[] permittedValues;
int position;
String documentation;
boolean orderByPosition = false;
while (gettersIter.hasNext()) {
getter = gettersIter.next();
slotClazz = getter.getReturnType();
mandatory = false;
manageAsSerializable = false;
cardMin = 0;
cardMax = ObjectSchema.UNLIMITED;
defaultValue = null;
regex = null;
permittedValues = null;
documentation = null;
aggregateType = null;
position = -1;
slotAnnotation = getter.getAnnotation(Slot.class);
aggregateSlotAnnotation = getter.getAnnotation(AggregateSlot.class);
// build the name of the bean property starting from the getter
propertyName = buildPropertyNameFromGetter(getter);
// build the name of the setter name coherent with bean rules
setterName = buildSetterNameFromBeanPropertyName(propertyName);
setter = setters.get(setterName);
if (setter != null) {
// ok, we have getter and setter, we need to check parameters consistency and we are done
if (accessorsAreConsistent(getter, setter)) {
/*
* if getter @Slot annotation provides a name, use it; otherwise
* use the bean property name
*/
String slotName = propertyName;
if (slotAnnotation != null) {
/*
* if there's a @Slot annotation which specifies the name of the slot, use it
*/
if (!Slot.USE_METHOD_NAME.equals(slotAnnotation.name())) {
slotName = slotAnnotation.name();
}
if (slotAnnotation.position() != -1) {
position = slotAnnotation.position();
orderByPosition = true;
}
if (!Slot.NULL.equals(slotAnnotation.defaultValue())) {
defaultValue = slotAnnotation.defaultValue();
}
if (!Slot.NULL.equals(slotAnnotation.regex())) {
regex = slotAnnotation.regex();
}
if (slotAnnotation.permittedValues().length > 0) {
permittedValues = slotAnnotation.permittedValues();
}
if (!Slot.NULL.equals(slotAnnotation.documentation())) {
documentation = slotAnnotation.documentation();
}
manageAsSerializable = slotAnnotation.manageAsSerializable();
mandatory = slotAnnotation.mandatory();
}
// if present, use getter @AggregateSlot annotation data
if (SlotAccessData.isAggregate(slotClazz)) {
if (slotClazz.isArray()) {
// extract the type of array elements
aggregateType = slotClazz.getComponentType();
}
Type slotType = getter.getGenericReturnType();
if (slotType instanceof ParameterizedType) {
ParameterizedType slotParameterizedType = (ParameterizedType)slotType;
Type[] actuals = slotParameterizedType.getActualTypeArguments();
// slotType must be an array or a Collection => we expect only 1 item in actuals
// get first element
if (actuals.length > 0) {
aggregateType = (Class)actuals[0];
}
}
// if (slotType has generics) {
// aggregateType = type from generics;
// }
if (aggregateSlotAnnotation != null) {
cardMin = aggregateSlotAnnotation.cardMin();
if (slotAnnotation == null && cardMin > 0) {
mandatory = true;
}
cardMax = aggregateSlotAnnotation.cardMax();
if (!Object.class.equals(aggregateSlotAnnotation.type())) {
aggregateType = aggregateSlotAnnotation.type();
}
}
}
sad = new SlotAccessData( slotClazz,
getter,