{
// Store the implementation-classes with the mapping
((InterfaceMapping) mapping).setImplementationClasses(fmd.getValueForExtension("implementation-classes"));
}
IdentifierFactory idFactory = storeMgr.getIdentifierFactory();
if (storeMgr.getOMFContext().getTypeManager().isReferenceType(javaType) && !serialised && !embedded)
{
// Reference mapping
// Create column(s) for the reference field (typically one column per implementation type)
createColumnsForReferenceField(mapping, table, fmd, isPrimaryKey, isNullable, serialised, embedded,
fieldRole, columnMetaData, clr);
}
else if (mapping instanceof ReferenceMapping ||
mapping instanceof SerialisedPCMapping ||
mapping instanceof SerialisedReferenceMapping ||
mapping instanceof PersistenceCapableMapping)
/*else if (!storeMgr.getOMFContext().getTypeManager().isSupportedType(javaType.getName()))*/
{
// PC mapping
JavaTypeMapping container = mapping;
if (mapping instanceof ReferenceMapping)
{
// Interface/Object has child mappings for each implementation
container = storeMgr.getDatastoreAdapter().getMapping(javaType, storeMgr, serialised, embedded, fmd != null ? fmd.getFullFieldName() : null);
((ReferenceMapping) mapping).addJavaTypeMapping(container);
}
if (container instanceof SerialisedPCMapping || container instanceof SerialisedReferenceMapping)
{
// Serialised column will be added by mapping constructor, so just return it
return mapping;
}
// Get the table that we want our column to be a FK to
// This could be the owner table, element table, key table, value table etc
DatastoreClass destinationTable = storeMgr.getDatastoreClass(javaType.getName(), clr);
if (destinationTable == null)
{
// Maybe the owner hasn't got its own table (e.g "subclass-table" inheritance strategy)
AbstractClassMetaData ownerCmd = storeMgr.getOMFContext().getMetaDataManager().getMetaDataForClass(javaType, clr);
AbstractClassMetaData[] ownerCmds = storeMgr.getClassesManagingTableForClass(ownerCmd, clr);
if (ownerCmds == null || ownerCmds.length == 0)
{
throw new JPOXUserException(LOCALISER.msg("057023", javaType.getName())).setFatal();
}
// Use the first one since they should all have the same id column(s)
destinationTable = storeMgr.getDatastoreClass(ownerCmds[0].getFullClassName(), clr);
}
if (destinationTable != null)
{
// Foreign-Key to the destination table
JavaTypeMapping m = destinationTable.getIDMapping();
// For each datastore mapping, add a column.
ColumnMetaDataContainer columnContainer = null;
if (columnMetaData != null && columnMetaData.length > 0)
{
columnContainer = (ColumnMetaDataContainer)columnMetaData[0].getParent();
}
CorrespondentColumnsMapper correspondentColumnsMapping =
new CorrespondentColumnsMapper(columnContainer, columnMetaData, m, true);
for (int i=0; i<m.getNumberOfDatastoreFields(); i++)
{
JavaTypeMapping refDatastoreMapping =
storeMgr.getDatastoreAdapter().getMapping(m.getDataStoreMapping(i).getJavaTypeMapping().getJavaType(), storeMgr);
ColumnMetaData colmd = correspondentColumnsMapping.getColumnMetaDataByIdentifier(
m.getDataStoreMapping(i).getDatastoreField().getIdentifier());
try
{
DatastoreIdentifier identifier = null;
if (colmd.getName() == null)
{
// User hasn't provided a name, so we use default naming
if (isReferenceField)
{
// Create reference identifier
identifier = idFactory.newReferenceFieldIdentifier(fmd,
storeMgr.getOMFContext().getMetaDataManager().getMetaDataForClass(javaType, clr),
m.getDataStoreMapping(i).getDatastoreField().getIdentifier(),
storeMgr.getOMFContext().getTypeManager().isDefaultEmbeddedType(javaType), fieldRole);
}
else
{
// Create join table identifier (FK using destination table identifier)
AbstractMemberMetaData[] relatedMmds = fmd.getRelatedMemberMetaData(clr);
// TODO Cater for more than 1 related field
identifier = ((RDBMSIdentifierFactory)idFactory).newJoinTableFieldIdentifier(fmd,
relatedMmds != null ? relatedMmds[0] : null,
m.getDataStoreMapping(i).getDatastoreField().getIdentifier(),
storeMgr.getOMFContext().getTypeManager().isDefaultEmbeddedType(javaType), fieldRole);
}
}
else
{
// User defined name, so we use that.
identifier = idFactory.newDatastoreFieldIdentifier(colmd.getName());
}
DatastoreField column = table.addDatastoreField(javaType.getName(), identifier, refDatastoreMapping, colmd);
((Column) m.getDataStoreMapping(i).getDatastoreField()).copyConfigurationTo(column);
if (isPrimaryKey)
{
column.setAsPrimaryKey();
}
if (isNullable)
{
column.setNullable();
}
storeMgr.getMappingManager().createDatastoreMapping(refDatastoreMapping, storeMgr, column,
m.getDataStoreMapping(i).getJavaTypeMapping().getJavaTypeForDatastoreMapping(i));
}
catch (DuplicateColumnNameException ex)
{
throw new JPOXUserException("Cannot create column for field "+fmd.getFullFieldName()+" column metadata "+colmd,ex);
}
((PersistenceCapableMapping) container).addJavaTypeMapping(refDatastoreMapping);
}
}
}
else
{
// Non-PC mapping
// Add column for the field
DatastoreField column = null;
ColumnMetaData colmd = null;
if (columnMetaData != null && columnMetaData.length > 0)
{
colmd = columnMetaData[0];
}
DatastoreIdentifier identifier = null;
if (colmd != null && colmd.getName() != null)
{
// User specified name
identifier = idFactory.newDatastoreFieldIdentifier(colmd.getName());
}
else
{
// No user-supplied name so generate one
identifier = ((RDBMSIdentifierFactory)idFactory).newJoinTableFieldIdentifier(fmd, null, null,