}
else if (localName.equals("secondary-table"))
{
// Join for this entity
ClassMetaData cmd = (ClassMetaData)getStack();
JoinMetaData joinmd = new JoinMetaData();
joinmd.setTable(getAttr(attrs, "name"));
joinmd.setCatalog(getAttr(attrs, "catalog"));
joinmd.setSchema(getAttr(attrs, "schema"));
cmd.addJoin(joinmd);
pushStack(joinmd);
}
else if (localName.equals("primary-key-join-column"))
{
MetaData md = getStack();
if (md instanceof ClassMetaData)
{
// Join columns between PK of subclass table and PK of base class table
ClassMetaData cmd = (ClassMetaData)md;
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setTarget(getAttr(attrs, "referenced-column-name"));
String columnDdl = getAttr(attrs, "column-definition");
if (columnDdl != null)
{
colmd.setColumnDdl(columnDdl);
}
InheritanceMetaData inhmd = cmd.getInheritanceMetaData();
if (inhmd == null)
{
inhmd = new InheritanceMetaData();
cmd.setInheritanceMetaData(inhmd);
}
JoinMetaData inhJoinmd = inhmd.getJoinMetaData();
if (inhJoinmd == null)
{
inhJoinmd = new JoinMetaData();
}
inhJoinmd.addColumn(colmd);
}
else if (md instanceof JoinMetaData)
{
// Join columns between PK of secondary table and PK of primary table
JoinMetaData joinmd = (JoinMetaData)md;
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setTarget(getAttr(attrs, "referenced-column-name"));
joinmd.addColumn(colmd);
}
}
else if (localName.equals("id"))
{
// Identity field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newPKFieldObject(cmd, attrs);
pushStack(mmd);
}
else if (localName.equals("embedded-id"))
{
// Embedded identity field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newPKFieldObject(cmd, attrs);
pushStack(mmd);
}
else if (localName.equals("basic"))
{
// Basic field
AbstractClassMetaData cmd = (AbstractClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
pushStack(mmd);
}
else if (localName.equals("lob"))
{
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
fmd.setStoreInLob(); // Just mark it as to be stored in a "lob" and let the MetaData sort it out
}
else if (localName.equals("enumerated"))
{
// Processed elsewhere
}
else if (localName.equals("temporal"))
{
// Processed elsewhere
}
else if (localName.equals("transient"))
{
// Transient field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newTransientFieldObject(cmd, getAttr(attrs, "name"));
cmd.addMember(mmd);
pushStack(mmd);
}
else if (localName.equals("one-to-many"))
{
// 1-N field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
String targetEntityName = getAttr(attrs, "target-entity");
if (!StringUtils.isWhitespace(targetEntityName))
{
mmd.setTargetClassName(targetEntityName);
}
mmd.setOrdered(); // Mark as ordered so we know we're using JPA
String jpaLevel = mgr.getOMFContext().getPersistenceConfiguration().getStringProperty("datanucleus.jpa.level");
if (mmd.getMappedBy() == null && mmd.getJoinMetaData() == null &&
jpaLevel.equalsIgnoreCase("JPA1"))
{
// JPA1 : 1-N uni with no join specified (yet) so add one (see JPA1 spec [9.1.24])
mmd.setJoinMetaData(new JoinMetaData());
}
pushStack(mmd);
}
else if (localName.equals("one-to-one"))
{
// 1-1 field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
String targetEntityName = getAttr(attrs, "target-entity");
if (!StringUtils.isWhitespace(targetEntityName))
{
mmd.setTargetClassName(targetEntityName);
}
pushStack(mmd);
}
else if (localName.equals("many-to-one"))
{
// N-1 field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
String targetEntityName = getAttr(attrs, "target-entity");
if (!StringUtils.isWhitespace(targetEntityName))
{
mmd.setTargetClassName(targetEntityName);
}
pushStack(mmd);
}
else if (localName.equals("many-to-many"))
{
// M-N field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
String targetEntityName = getAttr(attrs, "target-entity");
if (!StringUtils.isWhitespace(targetEntityName))
{
mmd.setTargetClassName(targetEntityName);
}
mmd.setOrdered(); // Mark as ordered so we know we're using JPA
if (mmd.getMappedBy() == null && mmd.getJoinMetaData() == null)
{
// M-N and no join specified (yet) so add one
mmd.setJoinMetaData(new JoinMetaData());
}
pushStack(mmd);
}
else if (localName.equals("map-key"))
{
// Key of a Map (field/property of the value class)
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
String mappedByFieldName = getAttr(attrs, "name");
if (StringUtils.isWhitespace(mappedByFieldName))
{
mappedByFieldName = "#PK"; // Special value understood by MapMetaData.populate()
}
KeyMetaData keymd = new KeyMetaData();
keymd.setMappedBy(mappedByFieldName);
fmd.setKeyMetaData(keymd);
}
else if (localName.equals("order-by"))
{
// Processed in endElement()
}
else if (localName.equals("order-column"))
{
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
String columnName = getAttr(attrs, "name");
OrderMetaData ordermd = new OrderMetaData();
ordermd.setColumnName(columnName);
String orderingOrigin = getAttr(attrs, "base");
if (orderingOrigin != null)
{
try
{
int origin = new Integer(orderingOrigin).intValue();
ordermd.setOrderOrigin(origin);
}
catch (NumberFormatException nfe)
{
}
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setAllowsNull(getAttr(attrs, "nullable"));
colmd.setInsertable(getAttr(attrs, "insertable"));
colmd.setUpdateable(getAttr(attrs, "updatable"));
String columnDdl = getAttr(attrs, "column-definition");
if (columnDdl != null)
{
colmd.setColumnDdl(columnDdl);
}
ordermd.addColumn(colmd);
fmd.setOrderMetaData(ordermd);
}
else if (localName.equals("cascade"))
{
// Do nothing
}
else if (localName.equals("cascade-type"))
{
// Handled in elements below
}
else if (localName.equals("cascade-all"))
{
AbstractMemberMetaData mmd = (AbstractMemberMetaData)getStack();
mmd.setCascadePersist(true);
mmd.setCascadeUpdate(true);
mmd.setCascadeDelete(true);
mmd.setCascadeRefresh(true);
}
else if (localName.equals("cascade-persist"))
{
MetaData md = getStack();
if (md instanceof AbstractMemberMetaData)
{
AbstractMemberMetaData mmd = (AbstractMemberMetaData)md;
mmd.setCascadePersist(true);
}
else if (md instanceof FileMetaData)
{
// Specified at <persistence-unit-defaults>
defaultCascadePersist = true;
}
}
else if (localName.equals("cascade-merge"))
{
AbstractMemberMetaData mmd = (AbstractMemberMetaData)getStack();
mmd.setCascadeUpdate(true);
}
else if (localName.equals("cascade-remove"))
{
AbstractMemberMetaData mmd = (AbstractMemberMetaData)getStack();
mmd.setCascadeDelete(true);
}
else if (localName.equals("cascade-refresh"))
{
AbstractMemberMetaData mmd = (AbstractMemberMetaData)getStack();
mmd.setCascadeRefresh(true);
}
else if (localName.equals("version"))
{
if (getStack() instanceof ClassMetaData)
{
// Version field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
// Tag this field as the version field
VersionMetaData vermd = cmd.newVersionMetadata();
vermd.setStrategy(VersionStrategy.VERSION_NUMBER).setFieldName(mmd.getName());
pushStack(mmd);
}
}
else if (localName.equals("discriminator-value"))
{
// Processed in endElement()
}
else if (localName.equals("discriminator-column"))
{
ClassMetaData cmd = (ClassMetaData)getStack();
InheritanceMetaData inhmd = cmd.getInheritanceMetaData();
if (inhmd == null)
{
// Add an empty inheritance specification
inhmd = new InheritanceMetaData();
cmd.setInheritanceMetaData(inhmd);
}
DiscriminatorMetaData dismd = inhmd.getDiscriminatorMetaData();
if (dismd == null)
{
// User hasn't specified discriminator value so use "provider-specific function" (JPA 9.1.3.1) - what a joke spec
dismd = inhmd.newDiscriminatorMetadata();
dismd.setStrategy(DiscriminatorStrategy.VALUE_MAP);
dismd.setValue(cmd.getFullClassName()); // Default to class name as value unless set
dismd.setIndexed("true");
}
String jdbcType = null;
String discType = getAttr(attrs, "discriminator-type");
if (discType != null)
{
if (discType.equalsIgnoreCase("STRING"))
{
jdbcType = "VARCHAR";
}
else if (discType.equalsIgnoreCase("CHAR"))
{
jdbcType = "CHAR";
}
else if (discType.equalsIgnoreCase("INTEGER"))
{
jdbcType = "INTEGER";
}
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setJdbcType(jdbcType);
String columnDdl = getAttr(attrs, "column-definition");
if (columnDdl != null)
{
colmd.setColumnDdl(columnDdl);
}
dismd.setColumnMetaData(colmd);
}
else if (localName.equals("generated-value"))
{
// generated value for this field
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
String strategy = getAttr(attrs, "strategy");
if (strategy != null)
{
if (strategy.equalsIgnoreCase("auto"))
{
fmd.setValueStrategy(IdentityStrategy.NATIVE);
}
else if (strategy.equalsIgnoreCase("table"))
{
fmd.setValueStrategy(IdentityStrategy.INCREMENT);
}
else if (strategy.equalsIgnoreCase("sequence"))
{
fmd.setValueStrategy(IdentityStrategy.SEQUENCE);
}
else if (strategy.equalsIgnoreCase("identity"))
{
fmd.setValueStrategy(IdentityStrategy.IDENTITY);
}
}
fmd.setValueGeneratorName(getAttr(attrs, "generator"));
}
else if (localName.equals("join-table"))
{
// Join table for this field
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
JoinMetaData joinmd = new JoinMetaData();
String tableName = getAttr(attrs, "name");
String schemaName = getAttr(attrs, "schema");
String catalogName = getAttr(attrs, "catalog");
fmd.setJoinMetaData(joinmd);
if (!StringUtils.isWhitespace(tableName))
{
fmd.setTable(tableName);
}
if (!StringUtils.isWhitespace(schemaName))
{
fmd.setSchema(schemaName);
}
if (!StringUtils.isWhitespace(catalogName))
{
fmd.setSchema(catalogName);
}
pushStack(joinmd);
}
else if (localName.equals("column"))
{
// Column for the current field
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setLength(getAttr(attrs, "length"));
colmd.setScale(getAttr(attrs, "scale"));
colmd.setAllowsNull(getAttr(attrs, "nullable"));
colmd.setInsertable(getAttr(attrs, "insertable"));
colmd.setUpdateable(getAttr(attrs, "updatable"));
colmd.setUnique(getAttr(attrs, "unique"));
String columnDdl = getAttr(attrs, "column-definition");
if (columnDdl != null)
{
colmd.setColumnDdl(columnDdl);
}
fmd.addColumn(colmd);
String table = getAttr(attrs, "table");
if (!StringUtils.isWhitespace(table))
{
// Using secondary table
fmd.setTable(table);
}
}
else if (localName.equals("join-column"))
{
MetaData md = getStack();
if (md instanceof JoinMetaData)
{
JoinMetaData joinmd = (JoinMetaData)md;
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setTarget(getAttr(attrs, "referenced-column-name"));
colmd.setAllowsNull(getAttr(attrs, "nullable"));
colmd.setInsertable(getAttr(attrs, "insertable"));
colmd.setUpdateable(getAttr(attrs, "updatable"));
colmd.setUnique(getAttr(attrs, "unique"));
String columnDdl = getAttr(attrs, "column-definition");
if (columnDdl != null)
{
colmd.setColumnDdl(columnDdl);
}
joinmd.addColumn(colmd);
}
else if (md instanceof AbstractMemberMetaData)
{
// N-1, 1-1, 1-N (FK). Just set <column> for the field. Is this correct for 1-N FK ?
AbstractMemberMetaData fmd = (AbstractMemberMetaData)md;
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setTarget(getAttr(attrs, "referenced-column-name"));
colmd.setAllowsNull(getAttr(attrs, "nullable"));
colmd.setInsertable(getAttr(attrs, "insertable"));
colmd.setUpdateable(getAttr(attrs, "updatable"));
colmd.setUnique(getAttr(attrs, "unique"));
fmd.addColumn(colmd);
}
}
else if (localName.equals("inverse-join-column"))
{
MetaData md = getStack();
if (md instanceof JoinMetaData)
{
// Join table column that is FK to the element table
JoinMetaData joinmd = (JoinMetaData)md;
ElementMetaData elemmd = null;
AbstractMemberMetaData fmd = (AbstractMemberMetaData)joinmd.getParent();
if (fmd.getElementMetaData() != null)
{
elemmd = fmd.getElementMetaData();
}
else
{
elemmd = new ElementMetaData();
fmd.setElementMetaData(elemmd);
}
ColumnMetaData colmd = new ColumnMetaData();
colmd.setName(getAttr(attrs, "name"));
colmd.setTarget(getAttr(attrs, "referenced-column-name"));
colmd.setAllowsNull(getAttr(attrs, "nullable"));
colmd.setInsertable(getAttr(attrs, "insertable"));
colmd.setUpdateable(getAttr(attrs, "updatable"));
colmd.setUnique(getAttr(attrs, "unique"));
elemmd.addColumn(colmd);
}
}
else if (localName.equals("unique-constraint"))
{
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Unique constraint on primary table
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
UniqueMetaData unimd = new UniqueMetaData();
unimd.setTable(cmd.getTable()); // Columns are in subelement
cmd.addUniqueConstraint(unimd);
pushStack(unimd);
}
else if (md instanceof JoinMetaData)
{
// Unique constraint on secondary table or join table
JoinMetaData joinmd = (JoinMetaData)md;
UniqueMetaData unimd = new UniqueMetaData();
joinmd.setUniqueMetaData(unimd);
pushStack(unimd);
}
}
else if (localName.equals("entity-listeners"))
{