String discriminatorName = entity.discriminatorName();
DiscriminatorType discriminatorType = entity.discriminatorType();
SubClass[] subClasses = entity.subClasses();
// create an object descriptor
ObjectDescriptor desc = new ObjectDescriptor();
desc.setType(clazz);
desc.setDiscriminatorName(discriminatorName);
desc.setDiscriminatorType(discriminatorType.toString());
// get BeanInfo
BeanInfo info = ReflectionUtil.getBeanInfo(clazz);
Map<Method, java.beans.PropertyDescriptor> methodMap
= new HashMap<Method, java.beans.PropertyDescriptor>();
for (java.beans.PropertyDescriptor pd : info.getPropertyDescriptors()) {
methodMap.put(pd.getReadMethod(), pd);
methodMap.put(pd.getWriteMethod(), pd);
}
// get all of the methods
for (Method method : clazz.getMethods()) {
// look for the annotations
Property property = method.getAnnotation(Property.class);
Id id = method.getAnnotation(Id.class);
if (property==null) {
continue;
}
// find pd
java.beans.PropertyDescriptor pd = methodMap.get(method);
if (pd==null) {
throw new MjormException(
method.getName()+" is not not a valid bean method.");
}
// "parse" data
String propField = !property.field().equals("")
? property.field()
: pd.getName();
Type propType = !property.type().equals(void.class)
? property.type()
: pd.getReadMethod().getGenericReturnType();
Type storageType = !property.storageType().equals(void.class)
? property.storageType()
: null;
Class<?> valueGeneratorClass = !property.valueGeneratorClass().equals(void.class)
? property.valueGeneratorClass()
: null;
Type[] genericParameterTypes = property.genericParameterTypes().length>0
? property.genericParameterTypes()
: new Type[0];
boolean propIsIdentifier = (id!=null);
boolean propIsAutoGen = (id!=null && id.autoGenerated());
// get the hints
Map<String, Object> hints = new HashMap<String, Object>();
if (property.typeConversionHints()!=null) {
for (TypeConversionHint hint : property.typeConversionHints()) {
hints.put(hint.name(), hint.stringValue());
}
}
// create the PropertyDescriptor
PropertyDescriptor prop = new PropertyDescriptor();
prop.setName(pd.getName());
prop.setFieldName(propField);
prop.setGetter(pd.getReadMethod());
prop.setSetter(pd.getWriteMethod());
prop.setIdentifier(propIsIdentifier);
prop.setType(JavaType.fromType(propType));
prop.setAutoGenerated(propIsAutoGen);
prop.setConversionHints(hints);
prop.setGenericParameterTypes(genericParameterTypes);
if (propIsAutoGen) {
ValueGenerator<?> valueGenerator = null;
if (valueGeneratorClass==null) {
valueGenerator = ObjectIdValueGenerator.INSTANCE;
storageType = ObjectId.class;
} else {
try {
valueGenerator = ValueGenerator.class.cast(valueGeneratorClass.newInstance());
} catch(Exception e) {
throw new IllegalArgumentException(
"Unable to create ValueGenerator for "+valueGeneratorClass.getName(), e);
}
}
prop.setValueGenerator(valueGenerator);
}
// set the storage type
if (storageType!=null) {
prop.setStorageType(JavaType.fromType(storageType));
}
// add to descriptor
desc.addPropertyDescriptor(prop);
}
// parse subclasses
for (SubClass subClassAnot : subClasses) {
// get discriminator value
Object discriminatorValue = MappingUtil.parseDiscriminator(
subClassAnot.discriminiatorValue(), discriminatorType);
// parse sub class
ObjectDescriptor subClass = parseClass(subClassAnot.entityClass(), descriptors);
// add subclass
desc.addSubClassObjectDescriptor(discriminatorValue, subClass);
descriptors.add(subClass);
}