MappingFilepublic class MappingFile extends Object This class supports the conversion between the iAS mapping file
format and the object used to represent that mapping to support
the iAS EJBC process and iAS CMP run-time. |
Fields Summary |
---|
private static final String | JAVA_TYPE_SET | private static final String | JAVA_TYPE_COLLECTION | private static final List | types | public static final String | DEFAULT_LOCATION_IN_EJB_JARDefinitive location for a mapping file in an ejb-jar file. | private static final com.sun.jdo.spi.persistence.utility.logging.Logger | loggerThe logger | private static final ResourceBundle | messagesI18N message handler | private Map | inverseRelationships | private Map | namedGroups | private int | groupCount | private ClassLoader | classLoader | private static int | MINIMUM_PRECISION | private ConversionHelper | helperAn object which implements ConversionHelper interface to
access data from other available sources to support the mapping
generation. | private HashMap | loadedSchema |
Constructors Summary |
---|
public MappingFile()Creates new MappingFile
classLoader = null;
| public MappingFile(ClassLoader cl)Creates new MappingFile
this();
classLoader = cl;
|
Methods Summary |
---|
private boolean | completeCmrMappings(SunCmpMapping beanSet)
// loop through the mappings to create a hash from bean name to em objects
Map beanName2EntityMapping = getBean2EntityMappingMap(beanSet);
Iterator emIter = beanName2EntityMapping.values().iterator();
boolean retVal = false;
String errorMsg = I18NHelper.getMessage(
messages,
"ERR_BAD_CONVERSION_HELPER"); //NOI18N
while (emIter.hasNext()) {
EntityMapping anEM = (EntityMapping) emIter.next();
String beanName = anEM.getEjbName();
String pt = anEM.getTableName();
CmrFieldMapping[] cmrsInEM = anEM.getCmrFieldMapping();
int len = 0;
if (null != cmrsInEM && !StringHelper.isEmpty(beanName))
len = cmrsInEM.length;
for (int i = 0; i < len; i++) {
String fieldName = cmrsInEM[i].getCmrFieldName();
if (!helper.hasField(beanName, fieldName)) {
throw new ConversionException(I18NHelper.getMessage(
messages,
"WARN_INVALID_CMRFIELD", //NOI18N
beanName, fieldName));
}
fieldName.trim().charAt(0);
String otherField = helper.getInverseFieldName(beanName,
fieldName);
if (otherField == null) {
throw new ConversionException(errorMsg);
}
String otherBean = helper.getRelationshipFieldContent(beanName,
fieldName);
if (otherBean == null) {
throw new ConversionException(errorMsg);
}
if (helper.isGeneratedRelationship(otherBean,otherField)) {
retVal = true;
String otherBeanName = helper.getRelationshipFieldContent(
beanName, fieldName);
otherBeanName.trim().charAt(0);
EntityMapping otherEM =
(EntityMapping) beanName2EntityMapping.get(
otherBeanName);
CmrFieldMapping inverseMapping = new CmrFieldMapping();
inverseMapping.setCmrFieldName(otherField);
inverseMapping.setColumnPair(
reverseCPArray(cmrsInEM[i].getColumnPair(), pt,
beanName, fieldName));
otherEM.addCmrFieldMapping(inverseMapping);
}
}
}
return retVal;
| private java.util.Collection | convertToColumnPairElements(ColumnPair[] pairs, java.lang.String primaryTableName, SchemaElement schema, java.util.Map knownTables, java.util.List tablesOfBean, java.lang.String relationId, MappingRelationshipElement mre)Converts column pair information from sun-cmp-mappings.xml into
column pair elements from the JDO mapping definition.
Collection primaryTableColumns = new ArrayList();
boolean isJoin = false;
for (int i = 0; null != pairs && i < pairs.length; i++) {
ColumnPair pair = pairs[i];
ColumnPairElement cpe = new ColumnPairElement();
boolean localSet = false;
cpe.setName(DBIdentifier.create(relationId + "_ColumnPair_" + i)); //NOI18N
for (int j = 0; j < 2; j++) {
String columnName = pair.getColumnName(j);
String sourceTableName = getTableName(columnName,
primaryTableName);
String sourceColumnName = getColumnName(columnName);
TableElement sourceTableEl = getTableElement(sourceTableName,
knownTables, schema);
ColumnElement ce = getColumnElement(sourceTableEl,
DBIdentifier.create(sourceColumnName), helper);
ce.toString();
// tablesOfBean stores the primary table and the secondary
// tables for the bean.
// It can be used for checking join table if sourceTableName
// is not in the tablesOfBean.
// If it is join table, should use addLocalColumn instead of
// addColumn.
if (j == 0) {
if (tablesOfBean.contains(sourceTableName)) {
localSet = true;
// Remember local columns for lower bound determination.
primaryTableColumns.add(ce);
}
else {
// join table
isJoin = true;
localSet = false;
}
}
if (cpe.getLocalColumn() == null) {
cpe.setLocalColumn(ce);
}
else {
cpe.setReferencedColumn(ce);
}
}
if (localSet) {
if (!isJoin) {
mre.addColumn(cpe);
}
else {
mre.addLocalColumn(cpe);
}
}
else if (isJoin) {
mre.addAssociatedColumn(cpe);
}
}
return primaryTableColumns;
| private MappingFieldElement | createMappingField(MappingClassElement mce, java.lang.String fieldName, ColumnElement col)
MappingFieldElement mfe =
new MappingFieldElementImpl(fieldName, mce);
mce.addField(mfe);
if (col != null)
mfe.addColumn(col);
return mfe;
| private void | createMappingForConsistency(EntityMapping mapping, MappingClassElement mce, java.lang.String beanName, java.util.Map knownTables)Load the consistency information. if it is version consistency, create
field mapping for version columns.
// load the consistency information
List versionColumns = loadConsistency(mapping, mce);
// If the consistency level is version consistency, the version field
// is always created, independent of the ConversionHelper's value for
// generateFields. This is because a generated version field is
// needed to hold the version column information.
if (versionColumns != null) {
String primaryTableName = mapping.getTableName();
// For 8.1 release, we only support one version column per bean
if (versionColumns.size() > 1) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_VERSION_COLUMNS")); //NOI18N
}
String versionColumn = (String)versionColumns.get(0);
String sourceTableName = getTableName(versionColumn,
primaryTableName);
// we do not support version column from secondary table
// in 8.1 release
if (!sourceTableName.equals(primaryTableName)) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"WARN_VERSION_COLUMN_INVALID_TABLE", //NOI18N
primaryTableName, beanName, versionColumn));
}
TableElement sourceTableEl = (TableElement) knownTables.get(
sourceTableName);
String versionColumnName = getColumnName(versionColumn);
ColumnElement versionCol = getColumnElement(sourceTableEl,
DBIdentifier.create(versionColumnName), helper);
if (null != versionCol) {
// Since 8.1 release only support one version column per bean,
// use prefix as the version field name
String fieldName = helper.getGeneratedVersionFieldNamePrefix();
PersistenceFieldElement pfe = createPersistenceField(mce,
fieldName);
MappingFieldElement mfe = createMappingField(mce, fieldName,
versionCol);
mfe.setVersion(true);
}
else {
// There is no version column.
// Report error.
throw new ConversionException(
I18NHelper.getMessage(
messages,
"WARN_VERSION_COLUMN_MISSING", //NOI18N
primaryTableName, beanName));
}
}
| private void | createMappingForUnknownPKClass(EntityMapping mapping, MappingClassElement mce, java.lang.String beanName, ColumnElement candidatePK)Create field mapping for unknown primary key
String primaryTableName = mapping.getTableName();
if (helper.generateFields()
&& helper.applyDefaultUnknownPKClassStrategy(beanName)) {
if (null != candidatePK) {
String fieldName = helper.getGeneratedPKFieldName();
// Fix later. Since mapping and persistence classes in the
// cache are only skeletons and not the one we want,
// put pce in a map at pce creation time for persistence
// class look up later to avoid a cast
// to MappingClassElementImpl.
PersistenceFieldElement pfe = createPersistenceField(mce,
fieldName);
pfe.setKey(true);
MappingFieldElement mfe = createMappingField(mce, fieldName,
candidatePK);
}
else {
// There is no column which meets primary key criteria.
// Report error.
throw new ConversionException(
I18NHelper.getMessage(
messages,
"WARN_NO_PKCOLUMN", //NOI18N
primaryTableName));
}
}
| private PersistenceFieldElement | createPersistenceField(MappingClassElement mce, java.lang.String fieldName)
PersistenceClassElement pce =
((MappingClassElementImpl)mce).getPersistenceElement();
PersistenceFieldElementImpl pfei =
new PersistenceFieldElementImpl(fieldName);
PersistenceFieldElement pfe =
new PersistenceFieldElement(pfei, pce);
pce.addField(pfe);
return pfe;
| private MappingFieldElement | createUnmappedField(MappingClassElement mce, java.lang.String beanName, java.lang.String fieldName)
PersistenceClassElement pce = ((MappingClassElementImpl)mce).
getPersistenceElement();
PersistenceFieldElementImpl pfei =
new PersistenceFieldElementImpl(fieldName);
PersistenceFieldElement pfe =
new PersistenceFieldElement(pfei, pce);
pfe.setKey(helper.isKey(beanName,fieldName,false));
pce.addField(pfe);
MappingFieldElement mfe = new MappingFieldElementImpl(fieldName, mce);
return mfe;
| public void | fromMappingClasses(java.io.OutputStream dest, java.util.Map mappingClasses, ConversionHelper helper)Creates an SunCmpMapping object from a Collection of
MappingClassElement objects
SunCmpMappings tmp = fromMappingClasses(mappingClasses, helper);
tmp.write(dest);
| public SunCmpMappings | fromMappingClasses(java.util.Map mappingClasses, ConversionHelper helper)Creates an SunCmpMapping object from a Collection of
MappingClassElement objects
Iterator keyIter = mappingClasses.keySet().iterator();
Map mapOfMapping = new java.util.HashMap();
while (keyIter.hasNext()) {
String ejbName = (String) keyIter.next();
MappingClassElement mce = (MappingClassElement)
mappingClasses.get(ejbName);
EntityMapping beanMapping = new EntityMapping();
if (null != mce) {
setConsistency(mce, beanMapping);
String schemaName = mce.getDatabaseRoot();
SunCmpMapping aMapping = (SunCmpMapping) mapOfMapping.get(
schemaName);
if (null == aMapping) {
aMapping = new SunCmpMapping();
aMapping.setSchema(schemaName);
mapOfMapping.put(schemaName, aMapping);
}
List tables = mce.getTables();
MappingTableElement primary = null;
if (tables.size() > 0) {
primary = (MappingTableElement) tables.get(0);
beanMapping.setTableName(primary.getName());
}
beanMapping.setEjbName(ejbName);
if (null != primary) {
List refKeys = primary.getReferencingKeys();
for (int i = 0; refKeys != null && i < refKeys.size(); i++) {
SecondaryTable sT = new SecondaryTable();
MappingReferenceKeyElement mrke =
(MappingReferenceKeyElement) refKeys.get(i);
MappingTableElement mte = mrke.getTable();
if (null != mte) {
sT.setTableName(mte.getName());
List cpnames = mrke.getColumnPairNames();
boolean hasPairs = false;
for (int j = 0; cpnames != null &&
j < cpnames.size(); j++) {
List token =
StringHelper.separatedListToArray((String)cpnames.get(j),";"); //NOI18N
ColumnPair cp = new ColumnPair();
Iterator iter = token.iterator();
while (iter.hasNext()) {
String columnName = (String)iter.next();
cp.addColumnName(columnName);
}
sT.addColumnPair(cp);
hasPairs = true;
}
if (hasPairs)
beanMapping.addSecondaryTable(sT);
else
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"WARN_ILLEGAL_PAIR", //NOI18N
new Object [] {ejbName, mte.getName(), cpnames}));
}
else {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"WARN_MISSING_TABLE", //NOI18N
new Object [] {ejbName, primary.getName()}));
}
}
}
else {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"WARN_NO_PRIMARY", //NOI18N
ejbName));
}
// transform the field mappings
PersistenceClassElement pce = null;
PersistenceFieldElement pfields[] = null;
if (mce instanceof MappingClassElementImpl) {
MappingClassElementImpl mcei =
(MappingClassElementImpl) mce;
pce = mcei.getPersistenceElement();
pfields = pce.getFields();
}
int len = 0;
if (null != pfields)
len = pfields.length;
for (int i = 0; i < len; i++) {
PersistenceFieldElement pfield = pfields[i];
String fieldName = pfield.getName();
if (helper.isGeneratedField(ejbName, fieldName)) {
continue;
}
if (pfield instanceof RelationshipElement) {
MappingRelationshipElement mre =
(MappingRelationshipElement) mce.getField(fieldName);
MappingFieldElement mfe = mre;
CmrFieldMapping cfm = new CmrFieldMapping();
cfm.setCmrFieldName(fieldName);
List cols = null;
if (null != mfe) {
cols = mfe.getColumns();
int fgVal = mfe.getFetchGroup();
setFetchedWith(cfm, fgVal);
}
for (int j = 0; null != cols && j < cols.size(); j++) {
String cpstring = (String) cols.get(j);
int slen = cpstring.indexOf(';");
ColumnPair cp = new ColumnPair();
cp.addColumnName(cpstring.substring(0,slen));
cp.addColumnName(cpstring.substring(slen+1));
cfm.addColumnPair(cp);
}
if (null != mre)
cols = mre.getAssociatedColumns();
for (int j = 0; null != cols && j < cols.size(); j++) {
String cpstring = (String) cols.get(j);
int slen = cpstring.indexOf(';");
ColumnPair cp = new ColumnPair();
cp.addColumnName(cpstring.substring(0,slen));
cp.addColumnName(cpstring.substring(slen+1));
cfm.addColumnPair(cp);
}
beanMapping.addCmrFieldMapping(cfm);
}
else {
MappingFieldElement mfe = mce.getField(fieldName);
CmpFieldMapping cfm = new CmpFieldMapping();
cfm.setFieldName(fieldName);
List cols = null;
if (null != mfe) {
cols = mfe.getColumns();
for (int j = 0; null != cols &&
j < cols.size(); j++) {
cfm.addColumnName((String)cols.get(j));
}
int fgVal = mfe.getFetchGroup();
setFetchedWith(cfm,fgVal);
}
beanMapping.addCmpFieldMapping(cfm);
}
}
aMapping.addEntityMapping(beanMapping);
}
}
SunCmpMappings retVal = null;
retVal = new SunCmpMappings();
Iterator mapOfMappingIter = mapOfMapping.values().iterator();
while (mapOfMappingIter.hasNext()) {
SunCmpMapping aVal = (SunCmpMapping) mapOfMappingIter.next();
retVal.addSunCmpMapping(aVal);
}
return retVal;
| private java.util.Map | getBean2EntityMappingMap(SunCmpMapping beanSet)
Map retVal = new HashMap();
EntityMapping [] entityMappingsInSet = beanSet.getEntityMapping();
int len = 0;
if (null != entityMappingsInSet)
len = entityMappingsInSet.length;
for (int k = 0; k < len; k++) {
EntityMapping anEntityMapping = entityMappingsInSet[k];
String beanName = anEntityMapping.getEjbName();
beanName.trim().charAt(0);
retVal.put(beanName,anEntityMapping);
}
return retVal;
| private ColumnElement | getCandidatePK(SchemaElement schema, java.lang.String primaryTableName)Get the candidate pk column for unknown primary key.
ColumnElement candidatePK = null;
TableElement primTabEl = getTableElement(schema,
DBIdentifier.create(primaryTableName), helper);
// Check if the candidatePK is really satisfying primary key
// criteria. It will be used only for unknown primary key.
UniqueKeyElement uke = primTabEl.getPrimaryKey();
if (null != uke) {
ColumnElement cols[] = uke.getColumns();
if (null != cols && 1 == cols.length) {
candidatePK = cols[0];
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_CANDIDATE_PK", //NOI18N
candidatePK.getName()));
Integer pre = candidatePK.getPrecision();
if (null != candidatePK && !candidatePK.isNumericType()) {
candidatePK = null;
}
if (null != candidatePK && (null != pre) && pre.intValue() < MINIMUM_PRECISION) {
candidatePK = null;
}
}
}
return candidatePK;
| private ColumnElement | getColumnElement(TableElement sourceTableEl, DBIdentifier sourceColumnName, ConversionHelper helper)
ColumnElement aCol = sourceTableEl.getColumn(sourceColumnName);
if (null == aCol && !helper.ensureValidation()) {
aCol = new ColumnElement();
aCol.setName(DBIdentifier.create(sourceTableEl.getName().toString()+"."+sourceColumnName.toString())); // NOI18N
aCol.setDeclaringTable(sourceTableEl);
aCol.setNullable(true);
}
if (aCol == null) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_COLUMN", //NOI18N
new Object [] {sourceColumnName, sourceTableEl}));
}
return aCol;
| private java.lang.String | getColumnName(java.lang.String columnName)
String retVal = columnName;
int len = columnName.lastIndexOf('.");
if (len > 0)
retVal = columnName.substring(len+1);
return retVal;
| private TableElement | getTableElement(java.lang.String tableName, java.util.Map knownTables, SchemaElement schema)Looks up the table element for tableName in the
table element cache knownTables . If the table
element is not found, the table name is looked up in the
database schema and registered in the cache.
TableElement te = (TableElement) knownTables.get(tableName);
if (null == te) {
te = getTableElement(schema, DBIdentifier.create(tableName),
helper);
knownTables.put(tableName, te);
}
return te;
| private TableElement | getTableElement(SchemaElement schema, DBIdentifier dbId, ConversionHelper helper)
TableElement retVal = ((schema != null) ?
schema.getTable(dbId) : null);
if (null == retVal && !helper.ensureValidation()) {
// Need to create a dummy for invalid mappings because
// the mapping model setter methods don't accept
// strings even though that is what they store.
// Create the table and add it to the knownTables list
// for later
retVal = new TableElement();
retVal.setName(dbId);
retVal.setDeclaringSchema(schema);
org.netbeans.modules.dbschema.UniqueKeyElement tkey =
new org.netbeans.modules.dbschema.UniqueKeyElement();
ColumnElement fakeKeyCol = new ColumnElement();
fakeKeyCol.setName(DBIdentifier.create(retVal.getName().getName()+ "."+"fookeyng")); //NOI18N
// Type numeric=2
fakeKeyCol.setType(2);
fakeKeyCol.setPrecision(new Integer(MINIMUM_PRECISION));
tkey.setPrimaryKey(true);
tkey.addColumn(fakeKeyCol);
retVal.addColumn(fakeKeyCol);
retVal.addKey(tkey);
}
if (retVal == null) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_TABLE", //NOI18N
new Object [] {dbId.getName(), schema}));
}
return retVal;
| private java.lang.String | getTableName(java.lang.String columnName, java.lang.String defaultName)
String retVal = defaultName;
int len = columnName.lastIndexOf('.");
if (len > 0)
retVal = columnName.substring(0,len);
return retVal;
| public java.util.Map | intoMappingClasses(SunCmpMappings content, ConversionHelper helper)Convert an SunCmpMapping object into the equivelent collection of
MappingClassElement objects
Map mces = new java.util.HashMap();
this.helper = helper;
boolean ensureValidation = helper.ensureValidation();
for (int i = 0; i < content.sizeSunCmpMapping(); i++) {
SunCmpMapping beanSet = content.getSunCmpMapping(i);
inverseRelationships = new HashMap();
namedGroups = new HashMap();
String schema = beanSet.getSchema();
if (helper.generateFields()) {
// sweep through the mappings to complete them
completeCmrMappings(beanSet);
}
// process bean mapping and fields mapping
for (int k = 0; k < beanSet.sizeEntityMapping(); k++) {
EntityMapping beanMapping = beanSet.getEntityMapping(k);
MappingClassElement aTpMapping = null;
if (ensureValidation) {
aTpMapping = mapFieldsOfBean(beanMapping, schema);
}
else {
try {
aTpMapping = mapFieldsOfBean(beanMapping, schema);
}
catch (ConversionException t) {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_CONV_EXC", //NOI18N
t.toString()));
}
}
mces.put(beanMapping.getEjbName(), aTpMapping);
}
}
return mces;
| public java.util.Map | intoMappingClasses(java.io.InputStream content, ConversionHelper helper)Convert an SunCmpMapping object into the equivelent collection of
MappingClassElement objects
SunCmpMappings foo = null;
try {
foo = SunCmpMappings.createGraph(content);
}
catch (Schema2BeansException t) {
if (helper.ensureValidation()) {
throw new ConversionException(
I18NHelper.getMessage(messages,
"XML_ERROR_IN_MAPPING_FILE", //NOI18N
DEFAULT_LOCATION_IN_EJB_JAR));
}
foo = SunCmpMappings.createGraph();
}
return intoMappingClasses(foo, helper);
| private boolean | isCascadeDelete(java.lang.String beanName, java.lang.String fieldName)Returns the cascade delete setting for the current relationship side.
The ConversionHelper interface provides cascade delete information
for the related side only.
final String beanInField = helper.getRelationshipFieldContent(beanName, fieldName);
final String inverseField = helper.getInverseFieldName(beanName,
fieldName);
return (null != beanInField && null != inverseField) ?
helper.relatedObjectsAreDeleted(beanInField, inverseField) : false;
| private boolean | isPartOfForeignKey(ColumnElement ce, ForeignKeyElement[] fks)Checks, if the column ce is part of one
of the foreign key constraints defined in fks .
RESOLVE: Method matchesFK in ModelValidator implements similar
functionality.
// RESOLVE: Column ce might be included in multiple foreign
// keys. The foreign key check applies to ALL relationships
// mapped to column ce. How can we find out, that a foreign
// key matches exactly the relationship being checked here?
if (fks != null) {
for (int index = 0; index < fks.length; index++) {
if (ce.equals(fks[index].getColumn(ce.getName()))) {
// The current ce is part of the foreign key.
return true;
}
}
}
return false;
| private boolean | isPartOfPrimaryKey(ColumnElement ce, UniqueKeyElement pk)Checks, if the column ce is part of the
primary key pk .
RESOLVE: Method isPrimaryKeyColumn in ModelValidator
implements similar functionality.
return null != pk && ce.equals(pk.getColumn(ce.getName()));
| private java.util.List | loadConsistency(EntityMapping mapping, MappingClassElement mce)Load consistency from schema2beans into MappingClassElement
Consistency c = mapping.getConsistency();
if (null == c) {
mce.setConsistencyLevel(MappingClassElement.NONE_CONSISTENCY);
}
else {
CheckVersionOfAccessedInstances versionIns =
(CheckVersionOfAccessedInstances)
c.getCheckVersionOfAccessedInstances();
if (c.isCheckModifiedAtCommit())
mce.setConsistencyLevel(
MappingClassElement.CHECK_MODIFIED_AT_COMMIT_CONSISTENCY);
else if(c.isLockWhenLoaded())
mce.setConsistencyLevel(
MappingClassElement.LOCK_WHEN_LOADED_CONSISTENCY);
else if(c.isCheckAllAtCommit())
mce.setConsistencyLevel(
MappingClassElement.CHECK_ALL_AT_COMMIT_CONSISTENCY);
else if(c.isLockWhenModified())
mce.setConsistencyLevel(
MappingClassElement.LOCK_WHEN_MODIFIED_CONSISTENCY);
else if(c.isLockWhenModified() && c.isCheckAllAtCommit())
mce.setConsistencyLevel(MappingClassElement.
LOCK_WHEN_MODIFIED_CHECK_ALL_AT_COMMIT_CONSISTENCY);
else if(c.isNone())
mce.setConsistencyLevel(MappingClassElement.NONE_CONSISTENCY);
else if (versionIns != null) {
mce.setConsistencyLevel(MappingClassElement.VERSION_CONSISTENCY);
List versionColumns = new ArrayList();
for (int i = 0; i < versionIns.sizeColumnName(); i++) {
versionColumns.add(versionIns.getColumnName(i));
}
return versionColumns;
}
else {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_CONSISTENCY_VALUE", mce)); //NOI18N
}
}
return null;
| private MappingClassElement | mapFieldsOfBean(EntityMapping mapping, java.lang.String schemaArg)Convert a bean's cmp-field-mapping and cmr-field-mapping elements into
mapping model objects.
The method can be called in two distinct cases:
1. At deployment time. The mapping must be complete enough to create a
valid mapping model, in order to support execution.
2. During mapping development. The mapping may be incomplete, but the
model objects that are created need to be as consistent as possible.
The absence of data should not be fatal, if possible.
String beanName = mapping.getEjbName();
MappingClassElement mce = null;
List tablesOfBean = new ArrayList();
Map knownTables = new HashMap();
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_START_BEAN", //NOI18N
beanName));
String jdoClassName = helper.getMappedClassName(beanName);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_JDOCLASS_NAME", //NOI18N
beanName, jdoClassName));
if (null == jdoClassName) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_CLASS", //NOI18N
beanName));
}
// create the mapping class element and its children
PersistenceClassElementImpl persistElImpl =
new PersistenceClassElementImpl(jdoClassName);
persistElImpl.setKeyClass(jdoClassName+".Oid"); //NOI18N
mce = new MappingClassElementImpl(
new PersistenceClassElement(persistElImpl));
SchemaElement schema = null;
// Assign the schema
if (!StringHelper.isEmpty(schemaArg))
schema = setDatabaseRoot(mce, schemaArg,
helper.ensureValidation());
// Map the table information
// Ensure the bean is mapped to a primary table.
if (!StringHelper.isEmpty(mapping.getTableName())) {
mapPrimaryTable(mapping, mce,
schema, knownTables, tablesOfBean);
mapSecondaryTables(mapping, mce,
schema, knownTables, tablesOfBean);
}
ColumnElement candidatePK = null;
// map the simple fields.
candidatePK = mapNonRelationshipFields(mapping, mce,
beanName, schema, knownTables);
createMappingForUnknownPKClass(mapping, mce,
beanName, candidatePK);
createMappingForConsistency(mapping, mce,
beanName, knownTables);
// map the relationship fields.
mapRelationshipFields(mapping, mce,
beanName, schema, knownTables, tablesOfBean);
// map any unmapped fields.
mapUnmappedFields(mce, beanName);
return mce;
| private ColumnElement | mapNonRelationshipFields(EntityMapping mapping, MappingClassElement mce, java.lang.String beanName, SchemaElement schema, java.util.Map knownTables)Map simple cmp field to MappingFieldElement
CmpFieldMapping [] mapOfFields = mapping.getCmpFieldMapping();
String primaryTableName = mapping.getTableName();
ColumnElement candidatePK = null;
// get candidate column only used for unknown primary key
if (helper.generateFields()
&& helper.applyDefaultUnknownPKClassStrategy(beanName)) {
candidatePK = getCandidatePK(schema, primaryTableName);
}
for (int i = 0; i < mapOfFields.length; i++) {
CmpFieldMapping mapForOneField = mapOfFields[i];
String fieldName = mapForOneField.getFieldName();
if (!validateField(mce, beanName, fieldName,
helper.ensureValidation())) {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"WARN_INVALID_FIELD", //NOI18N
beanName, fieldName));
continue;
}
String columnNames[] = mapForOneField.getColumnName();
MappingFieldElement mfe = createUnmappedField(mce, beanName,
fieldName);
boolean fieldMappedToABlob = false;
for (int j = 0; j < columnNames.length; j++) {
String sourceTableName = getTableName(columnNames[j],
primaryTableName);
if (null == sourceTableName) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_UNDEFINED_TABLE")); //NOI18N
}
String sourceColumnName = getColumnName(columnNames[j]);
// get the table element
TableElement sourceTableEl = getTableElement(sourceTableName,
knownTables, schema);
ColumnElement aCol = getColumnElement(sourceTableEl,
DBIdentifier.create(sourceColumnName), helper);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_ADD_COLUMN", //NOI18N
new Object [] {aCol, fieldName}));
// If candidatePK is mapped to a field, then it can not
// treated as a primary key for unknown primary key
if (helper.generateFields()
&& helper.applyDefaultUnknownPKClassStrategy(beanName)) {
if (candidatePK != null && candidatePK.equals(aCol)) {
candidatePK = null;
}
}
fieldMappedToABlob |= aCol.isBlobType();
mfe.addColumn(aCol);
}
FetchedWith fw = mapForOneField.getFetchedWith();
setFetchGroup(fw, mfe, beanName, fieldMappedToABlob);
mce.addField(mfe);
}
return candidatePK;
| private void | mapPrimaryTable(EntityMapping mapping, MappingClassElement mce, SchemaElement schema, java.util.Map knownTables, java.util.List tablesOfBean)Map the primary table of the bean.
String primaryTableName = mapping.getTableName();
TableElement primTabEl = getTableElement(primaryTableName, knownTables, schema);
mce.addTable(primTabEl);
tablesOfBean.add(primaryTableName);
| private void | mapRelationshipFields(EntityMapping mapping, MappingClassElement mce, java.lang.String beanName, SchemaElement schema, java.util.Map knownTables, java.util.List tablesOfBean)Converts entity mapping relationship information from sun-cmp-mappings.xml
into JDO mapping file information.
String primaryTableName = mapping.getTableName();
CmrFieldMapping mapOfRelations[] = mapping.getCmrFieldMapping();
PersistenceClassElement pce = ((MappingClassElementImpl)mce).getPersistenceElement();
for (int i = 0; mapOfRelations != null && i < mapOfRelations.length;
i++) {
CmrFieldMapping aRelation = mapOfRelations[i];
String fieldName = aRelation.getCmrFieldName();
if (!validateField(mce, beanName, fieldName, helper.ensureValidation())) {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"WARN_INVALID_CMRFIELD", //NOI18N
beanName, fieldName));
continue;
}
RelationshipElement rel = new RelationshipElement(
new RelationshipElementImpl(fieldName), pce);
MappingRelationshipElement mre =
new MappingRelationshipElementImpl(fieldName, mce);
// Register the inverse RelationshipElement
registerInverseRelationshipElement(rel, beanName, fieldName);
final ColumnPair pairs[] = aRelation.getColumnPair();
final String relationId = mapping.getEjbName() + "_Relationship_" + i; //NOI18N
Collection primaryTableColumns = convertToColumnPairElements(
pairs,
primaryTableName, schema, knownTables, tablesOfBean,
relationId,
mre);
setUpperBound(rel, beanName, fieldName);
setCascadeDeleteAction(rel, beanName, fieldName);
setLowerBound(rel,
primaryTableColumns,
primaryTableName,schema, knownTables,
beanName, fieldName);
setFetchGroup(aRelation.getFetchedWith(), mre, beanName, false);
pce.addField(rel);
mce.addField(mre);
}
| private void | mapSecondaryTables(EntityMapping mapping, MappingClassElement mce, SchemaElement schema, java.util.Map knownTables, java.util.List tablesOfBean)Map the secondary tables of the bean.
SecondaryTable [] tableList = mapping.getSecondaryTable();
List tl = mce.getTables();
if (null != tl && tl.size() > 0 && null != tl.get(0)) {
MappingTableElement primary = (MappingTableElement) tl.get(0);
for (int i = 0; null != tableList && i < tableList.length; i++) {
String tn = tableList[i].getTableName();
if (StringHelper.isEmpty(tn))
continue;
TableElement te = getTableElement(schema,
DBIdentifier.create(tn.trim()), helper);
ColumnPair pairs[] = tableList[i].getColumnPair();
int len = 0;
if (null != pairs)
len = pairs.length;
if (0 == len) {
if (logger.isLoggable(Logger.WARNING))
logger.warning(
I18NHelper.getMessage(
messages,
"WARN_NO_PAIRS", //NOI18N
new Object [] {mce, tn}));
continue;
}
MappingReferenceKeyElement mrke = mce.addSecondaryTable(
primary,te);
for (int j = 0; null != pairs && j < pairs.length; j++) {
ColumnPairElement cpe = new ColumnPairElement();
DBIdentifier dbId = DBIdentifier.create("SecondaryTable"+j); //NOI18N
cpe.setName(dbId);
ColumnPair pair = pairs[j];
for (int k = 0; k < 2; k++) {
String nameOne = pair.getColumnName(k);
String sourceTableName = getTableName(
nameOne.trim(),
primary.getName().toString());
String sourceColumnName = getColumnName(nameOne);
dbId = DBIdentifier.create(sourceTableName);
TableElement sourceTableEl = getTableElement(schema,
dbId, helper);
dbId = DBIdentifier.create(sourceColumnName);
ColumnElement ce = getColumnElement(sourceTableEl,
dbId, helper);
if (k == 0)
cpe.setLocalColumn(ce);
else
cpe.setReferencedColumn(ce);
}
mrke.addColumnPair(cpe);
}
knownTables.put(tn,te);
tablesOfBean.add(tn);
}
}
else
throw new ConversionException(
I18NHelper.getMessage(
messages,
"WARN_NOT_MAPPED_TO_PRIMARY", //NOI18N
mce.getName()));
| private void | mapUnmappedFields(MappingClassElement mce, java.lang.String beanName)Map unmapped field to mapping field object.
Object[] fields = helper.getFields(beanName);
if (!helper.ensureValidation()) {
for (int i = 0; i < fields.length; i++) {
String fieldName = (String) fields[i];
MappingFieldElement mfe = mce.getField(fieldName);
if (null == mfe) {
// this field needs a mapping created for it...
mfe = createUnmappedField(mce, beanName, fieldName);
mce.addField(mfe);
}
}
}
| private java.lang.String | qualify(java.lang.String tn, java.lang.String cn)
int tmp = cn.indexOf('.");
String retVal = cn;
if (-1 == tmp)
retVal = tn + "." + cn; // NOI18N
return retVal;
| private RelationshipElement | registerInverseRelationshipElement(RelationshipElement rel, java.lang.String beanName, java.lang.String fieldName)Registers relationship element rel in the cache
mapping field names to inverse relationship elements. The
inverse bean- and field names for the registration are
determined with the conversion helper. Returns the
relationship element for the inverse field, if this field has
been already processed, null otherwise.
String key = beanName + "." + fieldName; //NOI18N
RelationshipElement inverse = (RelationshipElement) inverseRelationships.get(key);
if (null == inverse) {
final String beanInField = helper.getRelationshipFieldContent(
beanName, fieldName);
final String inverseField = helper.getInverseFieldName(beanName,
fieldName);
if (null != beanInField && null != inverseField) {
key = beanInField + "." + inverseField; //NOI18N
inverseRelationships.put(key, rel);
}
}
else {
rel.changeInverseRelationship(inverse);
inverse.changeInverseRelationship(rel);
}
return inverse;
| private ColumnPair[] | reverseCPArray(ColumnPair[] cpa, java.lang.String primeTable, java.lang.String beanName, java.lang.String fieldName)
int len = (cpa == null) ? 0 : cpa.length;
if (len == 0) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_COLUMN_PAIR_MISSING", //NOI18N
beanName, fieldName));
}
ColumnPair [] retVal = new ColumnPair[len];
for (int index = 0; index < len; index++) {
retVal[index] = new ColumnPair();
retVal[index].addColumnName(
qualify(primeTable,cpa[index].getColumnName(1)));
retVal[index].addColumnName(
qualify(primeTable,cpa[index].getColumnName(0)));
}
return retVal;
| private void | setCascadeDeleteAction(RelationshipElement rel, java.lang.String beanName, java.lang.String fieldName)Sets the cascade delete option for relationship element
rel depending on the information from the
deployment descriptor. While the deployment descriptor
specifies cascade delete option on the dependent side, JDO
specifies it on the primary side. For this reason, the
information must be "switched".
if (helper.relatedObjectsAreDeleted(beanName, fieldName)) {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_REL_OBJ_DEL", //NOI18N
beanName, fieldName));
rel.setDeleteAction(RelationshipElement.CASCADE_ACTION);
}
| private void | setConsistency(MappingClassElement mce, EntityMapping beanMapping)Set consistency from MappingClassElement into schema2beans
Consistency bean.
int consistency = mce.getConsistencyLevel();
if (MappingClassElement.NONE_CONSISTENCY != consistency) {
Consistency c = new Consistency();
if (MappingClassElement.LOCK_WHEN_MODIFIED_CHECK_ALL_AT_COMMIT_CONSISTENCY == consistency) {
c.setLockWhenModified(true);
c.setCheckAllAtCommit(true);
}
if (MappingClassElement.LOCK_WHEN_MODIFIED_CONSISTENCY == consistency)
c.setLockWhenModified(true);
if (MappingClassElement.CHECK_ALL_AT_COMMIT_CONSISTENCY == consistency)
c.setCheckAllAtCommit(true);
if (MappingClassElement.LOCK_WHEN_LOADED_CONSISTENCY == consistency)
c.setLockWhenLoaded(true);
if (MappingClassElement.CHECK_MODIFIED_AT_COMMIT_CONSISTENCY == consistency)
c.setCheckModifiedAtCommit(true);
if (MappingClassElement.VERSION_CONSISTENCY == consistency) {
CheckVersionOfAccessedInstances versionIns =
new CheckVersionOfAccessedInstances();
Iterator iter = mce.getVersionFields().iterator();
while (iter.hasNext()) {
List columnNames = ((MappingFieldElement)iter.next()).
getColumns();
// vesion field only allow to map to one column
if (columnNames != null && columnNames.size() > 0)
versionIns.addColumnName((String)columnNames.get(0));
}
c.setCheckVersionOfAccessedInstances(versionIns);
}
beanMapping.setConsistency(c);
}
| private SchemaElement | setDatabaseRoot(MappingClassElement foo, java.lang.String schemaElementValue, boolean strict)
SchemaElement bar = null;
if (null != classLoader) {
if (loadedSchema.get(schemaElementValue) == null) {
SchemaElement.removeFromCache(schemaElementValue);
loadedSchema.put(schemaElementValue, schemaElementValue);
}
bar = SchemaElement.forName(schemaElementValue,classLoader);
}
else
bar = SchemaElement.forName(schemaElementValue);
if (strict) {
if (bar == null) {
// Prepare for a schema related error
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_CANNOT_FIND_SCHEMA", //NOI18N
new Object [] {schemaElementValue, classLoader}));
}
}
else {
if (null == bar) {
// conjure up a schema element and set its name...
// need to create a dummy for invalid mappings because the
// mapping model setter methods don't accept strings even
// though that is what they store.
bar = new SchemaElement();
DBIdentifier n = DBIdentifier.create(schemaElementValue);
n.setFullName(schemaElementValue);
bar.setName(n);
}
}
foo.setDatabaseRoot(bar);
return bar;
| private void | setFetchGroup(FetchedWith fw, MappingFieldElement mfe, java.lang.String beanName, boolean fieldMappedToABlob)Set fetch group level for mapping field and mapping relationship
element. If there is fetch level information, then set mapping field
element with the level. If there is no fetch group level information,
set mapping field element to GROUP_NONE if it is mapping relationship
element or blob type field otherwise set to GROUP_DEFAULT.
if (null != fw) {
boolean tryLevel = false;
int level = 0;
try {
level = fw.getLevel();
tryLevel = true;
}
catch (RuntimeException e) {
// If there is no level set, schema2beans throws
// RuntimeException.
// Need to do more investigation on why throws this exception.
// it is very likely that there is no level set, which would
// throw an exception here.. Which we are going to ignore
}
if (tryLevel) {
if (level < 1) {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_FG_LEVEL", //NOI18N
beanName, mfe.getName(), ""+level)); //NOI18N
}
mfe.setFetchGroup(level+1);
}
String ig = fw.getNamedGroup();
if (null != ig) {
Integer fgval = (Integer) namedGroups.get(ig);
if (null == fgval) {
fgval = new Integer(groupCount--);
namedGroups.put(ig,fgval);
}
mfe.setFetchGroup(fgval.intValue());
}
if (fw.isNone())
mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
if (fw.isDefault())
mfe.setFetchGroup(MappingFieldElement.GROUP_DEFAULT);
}
else {
if (mfe instanceof MappingRelationshipElement)
mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
else {
if (fieldMappedToABlob)
mfe.setFetchGroup(MappingFieldElement.GROUP_NONE);
else
mfe.setFetchGroup(MappingFieldElement.GROUP_DEFAULT);
}
}
| private void | setFetchedWith(HasFetchedWith cfm, int fgVal)Set fetchgroup in schema2beans FetchedWith bean
FetchedWith fw = new FetchedWith();
if (fgVal <= MappingFieldElement.GROUP_INDEPENDENT) {
String key = "IndependentFetchGroup"+fgVal; //NOI18N
fw.setNamedGroup(key);
}
else if (fgVal == MappingFieldElement.GROUP_DEFAULT) {
fw.setDefault(true);
}
else if (fgVal > MappingFieldElement.GROUP_DEFAULT) {
fw.setLevel(fgVal-1);
}
else if (fgVal == MappingFieldElement.GROUP_NONE) {
fw.setNone(true);
}
cfm.setFetchedWith(fw);
| private void | setLowerBound(RelationshipElement rel, java.util.Collection primaryTableColumns, java.lang.String primaryTableName, SchemaElement schema, java.util.Map knownTables, java.lang.String beanName, java.lang.String fieldName)If a non-collection relationship field is mapped to a
non-nullable column, the lower bound of the relationship might
be set to 1. To set the lower bound, we have to determine the
dependent side of the relationship. We set the lower bound to 1
based on the following rules:
- If the non-nullable column is not part of the primary key.
- If the local side has got a foreign key.
- If the local columns are a real subset of the primary key.
- If the user specified the local side for cascade delete.
rel.setLowerBound(0);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_NULL", //NOI18N
beanName, fieldName));
if (1 == rel.getUpperBound() && null != primaryTableName) {
boolean isPartOfPrimaryKey = false;
TableElement primaryTable = getTableElement(primaryTableName,
knownTables, schema);
UniqueKeyElement pk = primaryTable.getPrimaryKey();
ForeignKeyElement fks[] = primaryTable.getForeignKeys();
Iterator iter = primaryTableColumns.iterator();
while (iter.hasNext() && 0 == rel.getLowerBound()) {
ColumnElement ce = (ColumnElement) iter.next();
if (!ce.isNullable()) {
isPartOfPrimaryKey |= isPartOfPrimaryKey(ce, pk);
if (!isPartOfPrimaryKey) {
// We suppose that all primary key columns are non-nullable.
// If the non-nullable column is not part of the primary key,
// this is the dependent side.
rel.setLowerBound(1);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_NOPK", //NOI18N
beanName, fieldName));
}
// Check the foreign key constraint
else if (isPartOfForeignKey(ce, fks)) {
// If the non-nullable column is part of the foreign key,
// this is the dependent side.
rel.setLowerBound(1);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_FK", //NOI18N
beanName, fieldName));
}
}
}
if (0 == rel.getLowerBound() && isPartOfPrimaryKey) {
// The lower bound is still unset and all local columns
// are part of the primary key.
if (primaryTableColumns.size() < pk.getColumns().length) {
// The local columns are a real subset of the primary key.
// ==> This must be the dependent side.
rel.setLowerBound(1);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_PKSUBSET", //NOI18N
beanName, fieldName));
}
else if (isCascadeDelete(beanName, fieldName)) {
// This relationship side is marked as dependent side by the user.
rel.setLowerBound(1);
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_CASCADE", //NOI18N
beanName, fieldName));
}
else {
if (logger.isLoggable(Logger.FINE))
logger.fine(
I18NHelper.getMessage(
messages,
"MESSAGE_LWB_NODEPENDENT", //NOI18N
beanName, fieldName));
}
}
}
| private void | setUpperBound(RelationshipElement rel, java.lang.String beanName, java.lang.String fieldName)Sets the upper bound for relationship element rel
depending on the upper bound information from the deployment
descriptor and defines the element class for collection
relationship fields.
String beanInField = helper.getRelationshipFieldContent(beanName,
fieldName);
String classInJdoField = helper.getMappedClassName(beanInField);
String multiplicity = helper.getMultiplicity(beanName, fieldName);
// Set the upper bound.
if (multiplicity.equals(helper.MANY)) {
rel.setUpperBound(Integer.MAX_VALUE);
rel.setElementClass(classInJdoField);
String collectionClass = helper.getRelationshipFieldType(beanName,
fieldName);
if (types.contains(collectionClass)) {
rel.setCollectionClass(collectionClass);
}
else {
rel.setCollectionClass(null);
if (logger.isLoggable(Logger.WARNING))
logger.warning(
I18NHelper.getMessage(
messages,
"WARN_INVALID_RELATIONSHIP_FIELDTYPE", //NOI18N
beanName, fieldName, collectionClass));
}
}
else if (multiplicity.equals(helper.ONE)) {
rel.setUpperBound(1);
// Fix later. This code should be removed because in one side
// setElementClass should not be called.
// This line of code is for bug 4665051 which is plugin bug.
// It is likely that bug 4665051 indicates that there is code
// in the plugin which depends on the element class being set
// for a one side relationship.
rel.setElementClass(classInJdoField);
}
else {
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_BAD_MULTIPLICTY", //NOI18N
multiplicity, rel.getName()));
}
| private boolean | validateField(MappingClassElement mce, java.lang.String beanName, java.lang.String fieldName, boolean throwEx)
MappingFieldElement mfe = mce.getField(fieldName);
if (null != mfe) {
if (throwEx)
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_FIELD_MAPPED_TWICE", //NOI18N
beanName, fieldName));
else
return false;
}
if (!helper.hasField(beanName,fieldName)) {
if (throwEx)
throw new ConversionException(
I18NHelper.getMessage(
messages,
"ERR_INVALID_FIELD", //NOI18N
beanName, fieldName));
else
return false;
}
return true;
|
|