}
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);
mmd.setTargetClassName(getAttr(attrs, "target-entity"));
mmd.setOrdered();
if (mmd.getMappedBy() == null && mmd.getJoinMetaData() == null &&
!mgr.getOMFContext().getPersistenceConfiguration().getBooleanProperty("org.jpox.jpa.oneToManyUniFkRelations"))
{
// Strict JPA : 1-N uni with no join specified (yet) so add one (see JPA spec [9.1.24])
mmd.setJoinMetaData(new JoinMetaData(mmd, null, null, null, null, null, null, null, null));
}
pushStack(mmd);
}
else if (localName.equals("one-to-one"))
{
// 1-1 field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
mmd.setTargetClassName(getAttr(attrs, "target-entity"));
pushStack(mmd);
}
else if (localName.equals("many-to-one"))
{
// N-1 field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
mmd.setTargetClassName(getAttr(attrs, "target-entity"));
pushStack(mmd);
}
else if (localName.equals("many-to-many"))
{
// M-N field
ClassMetaData cmd = (ClassMetaData)getStack();
AbstractMemberMetaData mmd = newFieldObject(cmd, attrs);
mmd.setTargetClassName(getAttr(attrs, "target-entity"));
mmd.setOrdered();
if (mmd.getMappedBy() == null && mmd.getJoinMetaData() == null)
{
// M-N and no join specified (yet) so add one
mmd.setJoinMetaData(new JoinMetaData(mmd, null, null, null, null, null, null, null, null));
}
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(fmd, null, null, null, null, null, mappedByFieldName);
fmd.setKeyMetaData(keymd);
}
else if (localName.equals("order-by"))
{
// Processed in endElement()
}
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 = new VersionMetaData(VersionStrategy.VERSION_NUMBER.toString(), mmd.getName());
cmd.setVersionMetaData(vermd);
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, null);
cmd.setInheritanceMetaData(inhmd);
}
DiscriminatorMetaData discmd = inhmd.getDiscriminatorMetaData();
if (discmd == null)
{
// User hasnt specified discriminator value so use "provider-specific function" (JPA spec 9.1.3.1) - what a joke spec
discmd = new DiscriminatorMetaData(inhmd, null, null, DiscriminatorStrategy.CLASS_NAME.toString(), "true");
inhmd.setDiscriminatorMetaData(discmd);
}
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(discmd, getAttr(attrs, "name"), null, null, jdbcType, null, getAttr(attrs, "length"),
null, null, null, null, null, null, null);
discmd.setColumnMetaData(colmd);
}
else if (localName.equals("generated-value"))
{
// generated value for this field
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
IdentityStrategy idStrategy = IdentityStrategy.getIdentityStrategy(getAttr(attrs, "strategy"));
fmd.setValueStrategy(idStrategy);
fmd.setValueGeneratorName(getAttr(attrs, "generator"));
}
else if (localName.equals("join-table"))
{
// Join table for this field
AbstractMemberMetaData fmd = (AbstractMemberMetaData)getStack();
JoinMetaData joinmd = new JoinMetaData(fmd, null, null, null, null, null, null, null, null);
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(fmd,
getAttr(attrs, "name"),
null, // No "target" in JPA
null, // No "target-field" in JPA
null, // No "jdbc-type" in JPA (use Lob, Basic, Temporal to decide this)
null, // No "sql-type" in JPA
getAttr(attrs, "length"), // Should use precision if floating point type
getAttr(attrs, "scale"),
getAttr(attrs, "nullable"),
null, // No default-value in JPA
null, // No insert-value in JPA
getAttr(attrs, "insertable"),
getAttr(attrs, "updatable"),
getAttr(attrs, "unique"));
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(joinmd,
getAttr(attrs, "name"),
getAttr(attrs, "referenced-column-name"),
null,
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
getAttr(attrs, "nullable"),
null, // No default-value in JPA
null, // No insert-value in JPA
getAttr(attrs, "insertable"),
getAttr(attrs, "updatable"),
getAttr(attrs, "unique"));
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(fmd,
getAttr(attrs, "name"),
getAttr(attrs, "referenced-column-name"),
null,
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
getAttr(attrs, "nullable"),
null, // No default-value in JPA
null, // No insert-value in JPA
getAttr(attrs, "insertable"),
getAttr(attrs, "updatable"),
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, null, null, null, null, null, null);
fmd.setElementMetaData(elemmd);
}
ColumnMetaData colmd =
new ColumnMetaData(elemmd,
getAttr(attrs, "name"),
getAttr(attrs, "referenced-column-name"),
null,
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
null, // Copy referenced column
getAttr(attrs, "nullable"),
null, // No default-value in JPA
null, // No insert-value in JPA
getAttr(attrs, "insertable"),
getAttr(attrs, "updatable"),
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(null, cmd.getTable(), null); // 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(null, null, null);
joinmd.setUniqueMetaData(unimd);
pushStack(unimd);
}
}
else if (localName.equals("entity-listeners"))
{
// Nothing to add at this point
}
else if (localName.equals("entity-listener"))
{
MetaData md = getStack();
EventListenerMetaData elmd = new EventListenerMetaData(getAttr(attrs, "class"));
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
((AbstractClassMetaData)md).addListener(elmd);
}
else if (md instanceof FileMetaData)
{
// Specified at <persistence-unit-defaults>
((FileMetaData)md).addListener(elmd);
}
pushStack(elmd);
}
else if (localName.equals("pre-persist"))
{
// Pre-create callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PrePersist", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PrePersist", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("post-persist"))
{
// Post-create callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PostPersist", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PostPersist", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("pre-remove"))
{
// Pre-delete callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PreRemove", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PreRemove", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("post-remove"))
{
// Post-delete callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PostRemove", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PostRemove", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("pre-update"))
{
// Pre-store callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PreUpdate", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PreUpdate", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("post-update"))
{
// Post-store callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PostUpdate", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PostUpdate", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("post-load"))
{
// Post-load callback
MetaData md = getStack();
if (md instanceof AbstractClassMetaData)
{
// Specified at <entity> or <mapped-superclass>
AbstractClassMetaData cmd = (AbstractClassMetaData)md;
EventListenerMetaData elmd = cmd.getListenerForClass(cmd.getFullClassName());
if (elmd == null)
{
elmd = new EventListenerMetaData(cmd.getFullClassName());
cmd.addListener(elmd);
}
elmd.addCallback("javax.persistence.PostLoad", getAttr(attrs, "method-name"));
}
else
{
// Specified at <entity-listener>
EventListenerMetaData elmd = (EventListenerMetaData)md;
elmd.addCallback("javax.persistence.PostLoad", getAttr(attrs, "method-name"));
}
}
else if (localName.equals("attribute-override"))
{
// Override columns for a superclass field
AbstractClassMetaData cmd = (AbstractClassMetaData)getStack();
AbstractMemberMetaData fmd = newOverriddenFieldObject(cmd, attrs);
cmd.addMember(fmd);
pushStack(fmd);
}
else if (localName.equals("association-override"))
{
// Override columns for a superclass field
AbstractClassMetaData cmd = (AbstractClassMetaData)getStack();
AbstractMemberMetaData fmd = newOverriddenFieldObject(cmd, attrs);
cmd.addMember(fmd);
pushStack(fmd);
}
else if (localName.equals("exclude-default-listeners"))
{