aemd = new ValueMetaData();
mmd.setValueMetaData((ValueMetaData)aemd);
}
else
{
aemd = new ElementMetaData();
mmd.setElementMetaData((ElementMetaData)aemd);
}
for (int j = 0; j < elementColumns.size(); j++)
{
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(elementColumns.get(j).name());
colmd.setTarget(elementColumns.get(j).referencedColumnName());
colmd.setAllowsNull(elementColumns.get(j).nullable());
aemd.addColumn(colmd);
}
}
UniqueConstraint[] joinUniqueConstraints = (UniqueConstraint[])annotationValues.get("uniqueConstraints");
if (joinUniqueConstraints != null && joinUniqueConstraints.length > 0)
{
// Unique constraints on the join table
for (int j=0;j<joinUniqueConstraints.length;j++)
{
UniqueMetaData unimd = new UniqueMetaData();
for (int k=0;k<joinUniqueConstraints[j].columnNames().length;k++)
{
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(joinUniqueConstraints[j].columnNames()[k]);
unimd.addColumn(colmd);
}
joinmd.setUniqueMetaData(unimd); // JDO only supports a single unique constraint on a join table
}
}
}
else if (annName.equals(JPAAnnotationUtils.COLLECTION_TABLE))
{
// Process @CollectionTable to generate JoinMetaData
String tableName = (String)annotationValues.get("name");
if (!StringUtils.isWhitespace(tableName))
{
mmd.setTable(tableName);
}
String catalogName = (String)annotationValues.get("catalog");
if (!StringUtils.isWhitespace(catalogName))
{
mmd.setCatalog(catalogName);
}
String schemaName = (String)annotationValues.get("schema");
if (!StringUtils.isWhitespace(schemaName))
{
mmd.setSchema(schemaName);
}
joinmd = mmd.getJoinMetaData();
if (joinmd == null)
{
// Should always be set by @ElementCollection but add just in case
joinmd = new JoinMetaData();
mmd.setJoinMetaData(joinmd);
}
if (annotationValues.get("joinColumns") != null)
{
ArrayList<JoinColumn> joinColumns = new ArrayList<JoinColumn>();
joinColumns.addAll(Arrays.asList((JoinColumn[])annotationValues.get("joinColumns")));
for (int j = 0; j < joinColumns.size(); j++)
{
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(joinColumns.get(j).name());
colmd.setTarget(joinColumns.get(j).referencedColumnName());
colmd.setAllowsNull(joinColumns.get(j).nullable());
joinmd.addColumn(colmd);
}
}
UniqueConstraint[] joinUniqueConstraints = (UniqueConstraint[])annotationValues.get("uniqueConstraints");
if (joinUniqueConstraints != null && joinUniqueConstraints.length > 0)
{
// Unique constraints on the join table
for (int j=0;j<joinUniqueConstraints.length;j++)
{
UniqueMetaData unimd = new UniqueMetaData();
for (int k=0;k<joinUniqueConstraints[j].columnNames().length;k++)
{
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(joinUniqueConstraints[j].columnNames()[k]);
unimd.addColumn(colmd);
}
joinmd.setUniqueMetaData(unimd); // JDO only supports a single unique constraint on a join table
}
}
}
else if (annName.equals(JPAAnnotationUtils.MAP_KEY_COLUMN))
{
if (keymd == null)
{
keymd = new KeyMetaData();
mmd.setKeyMetaData(keymd);
}
String name = (String)annotationValues.get("name");
if (name != null)
{
keymd.setMappedBy(name);
}
Class keyType = mmd.getMap() != null && mmd.getMap().getKeyType() != null ? clr.classForName(mmd.getMap().getKeyType()) : Object.class;
keymd.addColumn(newColumnMetaData(keymd, keyType, annotations));
}
else if (annName.equals(JPAAnnotationUtils.MAP_KEY))
{
String keyMappedBy = (String)annotationValues.get("name");
if (keyMappedBy != null)
{
if (keymd == null)
{
keymd = new KeyMetaData();
mmd.setKeyMetaData(keymd);
}
keymd.setMappedBy(keyMappedBy);
if (mmd.getMap() != null &&
(mmd.getMap().getKeyType() == null || mmd.getMap().getKeyType().equals(Object.class.getName())))
{
// Set keyType based on mapped-by field of value class
String valueType = mmd.getMap().getValueType();
try
{
Class cls = clr.classForName(valueType);
try
{
Field fld = cls.getDeclaredField(keyMappedBy);
mmd.getMap().setKeyType(fld.getType().getName());
}
catch (NoSuchFieldException nsfe)
{
try
{
String getterName = ClassUtils.getJavaBeanGetterName(keyMappedBy, false);
Method mthd = cls.getDeclaredMethod(getterName, (Class[])null);
mmd.getMap().setKeyType(mthd.getReturnType().getName());
}
catch (NoSuchMethodException nsme)
{
}
}
}
catch (Exception e)
{
}
}
}
}
else if (annName.equals(JPAAnnotationUtils.MAP_KEY_ENUMERATED))
{
EnumType type = (EnumType)annotationValues.get("value");
if (keymd == null)
{
keymd = new KeyMetaData();
mmd.setKeyMetaData(keymd);
}
// TODO Merge with any @MapKey specification of the column
ColumnMetaData colmd = keymd.newColumnMetaData();
colmd.setJdbcType(type == EnumType.STRING ? "VARCHAR" : "INTEGER");
}
else if (annName.equals(JPAAnnotationUtils.ORDER_BY))
{
if (mmd.getOrderMetaData() != null)
{
throw new NucleusException("@OrderBy found yet field=" +
cmd.getFullClassName() + "." + member.getName() +
" already has ordering information!");
}
String orderBy = (String)annotationValues.get("value");
if (orderBy != null)
{
// "Ordered List"
OrderMetaData ordmd = new OrderMetaData();
ordmd.setOrdering(orderBy);
mmd.setOrderMetaData(ordmd);
}
}
else if (annName.equals(JPAAnnotationUtils.ORDER_COLUMN))
{
if (mmd.getOrderMetaData() != null)
{
throw new NucleusException("@OrderColumn found yet field=" +
cmd.getFullClassName() + "." + member.getName() +
" already has ordering information!");
}
String columnName = (String)annotationValues.get("name");
OrderMetaData ordermd = new OrderMetaData();
ordermd.setColumnName(columnName);
String colNullable = null;
String colInsertable = null;
String colUpdateable = null;
if (annotationValues.get("nullable") != null)
{
colNullable = annotationValues.get("nullable").toString();
}
if (annotationValues.get("insertable") != null)
{
colInsertable = annotationValues.get("insertable").toString();
}
if (annotationValues.get("updatable") != null)
{
// Note : "updatable" is spelt incorrectly in the JPA spec.
colUpdateable = annotationValues.get("updatable").toString();
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(columnName);
colmd.setAllowsNull(colNullable);
colmd.setInsertable(colInsertable);
colmd.setUpdateable(colUpdateable);
String tmp = (String)annotationValues.get("columnDefinition");
if (!StringUtils.isWhitespace(tmp))
{
colmd.setColumnDdl(tmp);
}
ordermd.addColumn(colmd);
mmd.setOrderMetaData(ordermd);
}
else if (annName.equals(JPAAnnotationUtils.ONE_TO_MANY))
{
// 1-N relation
oneToMany = true;
}
else if (annName.equals(JPAAnnotationUtils.MANY_TO_MANY))
{
// M-N relation
manyToMany = true;
}
}
// Post-processing to apply JPA rules for field relationships etc
if (oneToMany && mmd.getJoinMetaData() == null && mmd.getMappedBy() == null &&
jpaLevel.equalsIgnoreCase("JPA1"))
{
// 1-N with no join specified and unidirectional so JPA says it has to be via join (no 1-N uni FKs)
mmd.setJoinMetaData(new JoinMetaData());
}
if (manyToMany && mmd.getJoinMetaData() == null && mmd.getMappedBy() == null)
{
// M-N with no join specified and unidir so add the join for them
mmd.setJoinMetaData(new JoinMetaData());
}
if (mmd.getOrderMetaData() == null && Collection.class.isAssignableFrom(member.getType()))
{
// @OrderBy not specified but is a Collection so use ordering of element using PK field(s)
OrderMetaData ordmd = new OrderMetaData();
ordmd.setOrdering("#PK"); // Special value recognised by OrderMetaData
mmd.setOrderMetaData(ordmd);
}
if (columnMetaData == null)
{
// Column specified (at least in part) via @Column/@Lob/@Enumerated/@Temporal
ColumnMetaData colmd = newColumnMetaData(mmd, member.getType(), annotations);
if (colmd != null)
{
columnMetaData = new ColumnMetaData[1];
columnMetaData[0] = colmd;
}
}
if (columnMetaData != null)
{
// Column definition provided so apply to the respective place
if ((mmd.hasCollection() || mmd.hasArray()) && joinmd == null)
{
// Column is for the FK of the element of the collection/array
ElementMetaData elemmd = mmd.getElementMetaData();
if (elemmd == null)
{
elemmd = new ElementMetaData();
mmd.setElementMetaData(elemmd);
}
for (int i=0;i<columnMetaData.length;i++)
{
elemmd.addColumn(columnMetaData[i]);
}
}
else if (mmd.hasMap() && joinmd == null)
{
// Column is for the FK value of the map
ValueMetaData valmd = mmd.getValueMetaData();
if (valmd == null)
{
valmd = new ValueMetaData();
mmd.setValueMetaData(valmd);
}
for (int i=0;i<columnMetaData.length;i++)
{
valmd.addColumn(columnMetaData[i]);
}
}
else if (elementCollection)
{
// Column is for element/value column(s) of join table of 1-N of non-PCs
if (mmd.hasCollection() || mmd.hasArray())
{
ElementMetaData elemmd = mmd.getElementMetaData();
if (elemmd == null)
{
elemmd = new ElementMetaData();
mmd.setElementMetaData(elemmd);
}
for (int i=0;i<columnMetaData.length;i++)
{
elemmd.addColumn(columnMetaData[i]);
}
}
else if (mmd.hasMap())
{
ValueMetaData valmd = mmd.getValueMetaData();