/*
* Copyright (C) 2004 Anthony Smith
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* ----------------------------------------------------------------------------
* TITLE $Id$
* ---------------------------------------------------------------------------
*
* --------------------------------------------------------------------------*/
package opendbcopy.plugin.schemageneration;
import opendbcopy.config.APM;
import opendbcopy.config.XMLTags;
import opendbcopy.controller.MainController;
import opendbcopy.io.PropertiesToFile;
import opendbcopy.io.Writer;
import opendbcopy.plugin.model.DynamicPluginThread;
import opendbcopy.plugin.model.Model;
import opendbcopy.plugin.model.database.DatabaseModel;
import opendbcopy.plugin.model.database.typeinfo.TypeMapping;
import opendbcopy.plugin.model.exception.MissingAttributeException;
import opendbcopy.plugin.model.exception.MissingElementException;
import opendbcopy.plugin.model.exception.PluginException;
import opendbcopy.plugin.model.exception.UnsupportedAttributeValueException;
import org.jdom.Element;
import java.io.File;
import java.io.IOException;
import java.sql.DatabaseMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* class description
*
* @author Anthony Smith
* @version $Revision$
*/
public class GenerateHibernateMappingPlugin extends DynamicPluginThread {
private static final String HBM_FILE_SUFFIX = ".hbm.xml";
private static final String MANY_TO_ONE_REF_EXTENSION = "Ref";
private DatabaseModel model;
private TypeMapping typeMapping;
private StringBuffer sb;
private Element conf;
private File outputPath;
private String packageName;
private String hibernateDialect;
private String database = "";
private String uniqueKeyGenerator = "";
private String identifierQuoteStringOut = "";
private String outerJoin;
private boolean show_qualified_table_name = false;
private boolean lazy;
private boolean inverse;
private int counterRecords = 0;
private int counterTables = 0;
private List processTables;
/**
* Creates a new CopyMapping object.
*
* @param controller DOCUMENT ME!
* @param baseModel DOCUMENT ME!
*
* @throws PluginException DOCUMENT ME!
*/
public GenerateHibernateMappingPlugin(MainController controller,
Model baseModel) throws PluginException {
super(controller, baseModel);
this.model = (DatabaseModel) baseModel;
}
/**
* DOCUMENT ME!
*
* @throws PluginException DOCUMENT ME!
*/
protected void setUp() throws PluginException {
try {
// setup SQL Type -> Java Type Mapping up as HashMap for fast lookup
typeMapping = new TypeMapping(getTypeMapping());
// read the plugin configuration
conf = model.getConf();
outputPath = new File(conf.getChild(XMLTags.DIR).getAttributeValue(XMLTags.VALUE));
if (!outputPath.exists()) {
boolean mkDirOk = outputPath.mkdir();
if (!mkDirOk) {
throw new PluginException("Could not create " + outputPath.getAbsolutePath());
}
}
packageName = conf.getChild(XMLTags.PACKAGE_NAME).getAttributeValue(XMLTags.VALUE);
hibernateDialect = conf.getChild(XMLTags.HIBERNATE_DIALECT).getAttributeValue(XMLTags.CLASS);
outerJoin = conf.getChild(XMLTags.OUTER_JOIN).getAttributeValue(XMLTags.VALUE);
lazy = Boolean.valueOf(conf.getChild(XMLTags.LAZY).getAttributeValue(XMLTags.VALUE)).booleanValue();
inverse = Boolean.valueOf(conf.getChild(XMLTags.INVERSE).getAttributeValue(XMLTags.VALUE)).booleanValue();
// retrieve unique key generator
uniqueKeyGenerator = conf.getChild(XMLTags.GENERATOR_CLASS).getAttributeValue(XMLTags.VALUE);
if (model.getDbMode() == model.DUAL_MODE) {
database = model.getDestinationDb().getName();
} else {
database = model.getSourceDb().getName();
}
// extract the tables to dump
if (model.getDbMode() == model.DUAL_MODE) {
processTables = model.getDestinationTablesToProcessOrdered();
} else {
processTables = model.getSourceTablesToProcessOrdered();
}
int nbrTables = processTables.size();
// now set the number of tables that need to be copied
model.setLengthProgressTable(nbrTables);
} catch (Exception e) {
throw new PluginException(e.getMessage());
}
}
/**
* DOCUMENT ME!
*
* @throws PluginException DOCUMENT ME!
*/
public final void execute() throws PluginException {
try {
String destinationTableName = "";
String tableName = "";
String fileName = "";
Iterator itProcessTables = processTables.iterator();
while (itProcessTables.hasNext() && !isInterrupted()) {
Element tableProcess = (Element) itProcessTables.next();
List processColumns = null;
counterRecords = 0;
if (model.getDbMode() == model.DUAL_MODE) {
destinationTableName = tableProcess.getAttributeValue(XMLTags.DESTINATION_DB);
processColumns = model.getMappingColumnsToProcessByDestinationTable(destinationTableName);
fileName = outputPath.getAbsolutePath() + APM.FILE_SEP + destinationTableName + HBM_FILE_SUFFIX;
}
sb = new StringBuffer();
genHibernateMappingFile(destinationTableName, processColumns);
Writer.write(sb, fileName);
logger.info(fileName + " written");
model.setCurrentProgressTable(++counterTables);
}
// create hibernate.properties file
Properties p = new Properties();
Element destinationDriver = model.getDestinationConnection();
Element destinationDbProductName = model.getDestinationMetadata().getChild(XMLTags.DB_PRODUCT_NAME);
p.setProperty("hibernate.connection.driver_class", destinationDriver.getAttributeValue(XMLTags.DRIVER_CLASS));
p.setProperty("hibernate.connection.url", destinationDriver.getAttributeValue(XMLTags.URL));
if ((destinationDriver.getAttributeValue(XMLTags.USERNAME) == null) || (destinationDriver.getAttributeValue(XMLTags.USERNAME).length() == 0)) {
p.setProperty("hibernate.connection.username", "");
} else {
p.setProperty("hibernate.connection.username", destinationDriver.getAttributeValue(XMLTags.USERNAME));
}
if ((destinationDriver.getAttributeValue(XMLTags.PASSWORD) == null) || (destinationDriver.getAttributeValue(XMLTags.PASSWORD).length() == 0)) {
p.setProperty("hibernate.connection.password", "");
} else {
p.setProperty("hibernate.connection.password", destinationDriver.getAttributeValue(XMLTags.PASSWORD));
}
p.setProperty("hibernate.dialect", hibernateDialect);
if ((destinationDbProductName != null) && (destinationDbProductName.getAttributeValue(XMLTags.VALUE) != null)) {
p.setProperty(XMLTags.DB_PRODUCT_NAME, destinationDbProductName.getAttributeValue(XMLTags.VALUE));
} else {
p.setProperty(XMLTags.DB_PRODUCT_NAME, "unknown");
}
PropertiesToFile.exportPropertiesToFile(p, outputPath.getAbsolutePath() + APM.FILE_SEP + "hibernate.properties");
logger.info("hibernate properties written to " + outputPath.getAbsolutePath() + APM.FILE_SEP + "hibernate.properties");
if (!isInterrupted()) {
logger.info(counterTables + " table(s) processed");
logger.info("Please see user manual for documentation on how to continue");
}
} catch (MissingAttributeException e) {
throw new PluginException(e);
} catch (UnsupportedAttributeValueException e) {
throw new PluginException(e);
} catch (MissingElementException e) {
throw new PluginException(e);
} catch (IOException e) {
throw new PluginException(e);
}
}
/**
* DOCUMENT ME!
*
* @param destinationTableName DOCUMENT ME!
* @param processColumns DOCUMENT ME!
*
* @throws MissingAttributeException DOCUMENT ME!
* @throws UnsupportedAttributeValueException DOCUMENT ME!
* @throws MissingElementException DOCUMENT ME!
*/
private void genHibernateMappingFile(String destinationTableName,
List processColumns) throws MissingAttributeException, UnsupportedAttributeValueException, MissingElementException {
initXMLHeader();
sb.append("<hibernate-mapping>" + APM.LINE_SEP);
sb.append("<class name=\"" + packageName + "." + destinationTableName + "\" table=\"" + destinationTableName + "\">" + APM.LINE_SEP);
HashMap mapPrimaryKeyElements = new HashMap();
HashMap mapImportedKeyElements = new HashMap();
HashMap mapExportedKeyElements = new HashMap();
HashMap mapIndexElements = new HashMap();
ArrayList listImportedKeyElementsOrdered = new ArrayList();
// check for primary keys
if ((model.getDestinationPrimaryKeys(destinationTableName) != null) && (model.getDestinationPrimaryKeys(destinationTableName).size() > 0)) {
Iterator itPrimaryKeys = model.getDestinationPrimaryKeys(destinationTableName).iterator();
while (itPrimaryKeys.hasNext()) {
Element pkElement = (Element) itPrimaryKeys.next();
mapPrimaryKeyElements.put(pkElement.getAttributeValue(XMLTags.COLUMN_NAME), pkElement);
}
}
// check for imported keys
if ((model.getDestinationImportedKeys(destinationTableName) != null) && (model.getDestinationImportedKeys(destinationTableName).size() > 0)) {
Iterator itImportedKeys = model.getDestinationImportedKeys(destinationTableName).iterator();
while (itImportedKeys.hasNext()) {
Element impElement = (Element) itImportedKeys.next();
mapImportedKeyElements.put(impElement.getAttributeValue(XMLTags.FKCOLUMN_NAME), impElement);
listImportedKeyElementsOrdered.add(impElement);
}
}
// check for exported keys
if ((model.getDestinationExportedKeys(destinationTableName) != null) && (model.getDestinationExportedKeys(destinationTableName).size() > 0)) {
Iterator itExportedKeys = model.getDestinationExportedKeys(destinationTableName).iterator();
while (itExportedKeys.hasNext()) {
Element expElement = (Element) itExportedKeys.next();
mapExportedKeyElements.put(expElement.getAttributeValue(XMLTags.FKTABLE_NAME), expElement);
}
}
// check for indexes
if ((model.getDestinationIndexes(destinationTableName) != null) && (model.getDestinationIndexes(destinationTableName).size() > 0)) {
Iterator itIndexes = model.getDestinationIndexes(destinationTableName).iterator();
while (itIndexes.hasNext()) {
Element indexElement = (Element) itIndexes.next();
mapIndexElements.put(indexElement.getAttributeValue(XMLTags.COLUMN_NAME), indexElement);
}
}
// split columns into different lists
ArrayList normalColumns = new ArrayList();
ArrayList primaryKeyColumns = new ArrayList();
ArrayList importedKeyColumns = new ArrayList();
Element column = null;
for (int i = 0; i < processColumns.size(); i++) {
column = (Element) processColumns.get(i);
column = model.getDestinationColumn(destinationTableName, column.getAttributeValue(XMLTags.DESTINATION_DB));
if (mapPrimaryKeyElements.containsKey(column.getAttributeValue(XMLTags.NAME))) {
primaryKeyColumns.add(column);
} else if (mapImportedKeyElements.containsKey(column.getAttributeValue(XMLTags.NAME))) {
importedKeyColumns.add(column);
} else {
normalColumns.add(column);
}
}
// single primary key column
if (primaryKeyColumns.size() == 1) {
processSinglePrimaryKey(sb, (Element) primaryKeyColumns.get(0), destinationTableName);
}
// compound primary key
else {
processCompositeKey(sb, destinationTableName, mapImportedKeyElements, listImportedKeyElementsOrdered, primaryKeyColumns);
}
// Process normal columns
for (int i = 0; i < normalColumns.size(); i++) {
processNormalColumn(sb, mapIndexElements, (Element) normalColumns.get(i));
}
// imported keys
processImportedKeys(sb, mapImportedKeyElements, importedKeyColumns);
// exported key
if (mapExportedKeyElements.size() > 0) {
Iterator itExportedKeys = mapExportedKeyElements.values().iterator();
while (itExportedKeys.hasNext()) {
processExportedKey((Element) itExportedKeys.next());
}
}
sb.append("</class>" + APM.LINE_SEP);
sb.append("</hibernate-mapping>" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*/
private void initXMLHeader() {
sb.append("<?xml version=\"1.0\"?>" + APM.LINE_SEP);
sb.append("<!DOCTYPE hibernate-mapping PUBLIC \"-//Hibernate/Hibernate Mapping DTD 2.0//EN\" \"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd\">" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param column DOCUMENT ME!
* @param tableName DOCUMENT ME!
*
* @throws MissingAttributeException DOCUMENT ME!
* @throws UnsupportedAttributeValueException DOCUMENT ME!
* @throws MissingElementException DOCUMENT ME!
*/
private void processSinglePrimaryKey(StringBuffer sb,
Element column,
String tableName) throws MissingAttributeException, UnsupportedAttributeValueException, MissingElementException {
sb.append("<id");
sb.append(" name=\"" + column.getAttributeValue(XMLTags.NAME) + "\"");
sb.append(" column=\"" + column.getAttributeValue(XMLTags.NAME) + "\"");
sb.append(" type=\"" + typeMapping.getJavaType(column.getAttributeValue(XMLTags.DATA_TYPE)) + "\"");
sb.append(">" + APM.LINE_SEP);
// add params if available - and replace [table] patterns
Element generatorElement = null;
Iterator itGeneratorElements = conf.getChild(XMLTags.GENERATOR_CLASS).getChildren().iterator();
while (itGeneratorElements.hasNext() && (generatorElement == null)) {
Element element = (Element) itGeneratorElements.next();
if (element.getAttributeValue(XMLTags.CLASS).compareTo(uniqueKeyGenerator) == 0) {
generatorElement = element;
}
}
if ((generatorElement != null) && (generatorElement.getChildren().size() > 0)) {
sb.append(" <generator class=\"" + uniqueKeyGenerator + "\">" + APM.LINE_SEP);
List children = conf.getChild(XMLTags.GENERATOR_CLASS).getChild(uniqueKeyGenerator).getChildren();
for (int i = 0; i < children.size(); i++) {
Element child = (Element) children.get(i);
sb.append(" <" + child.getName() + " name=\"" + child.getAttributeValue(XMLTags.NAME) + "\"" + ">");
String text = child.getText();
if ((text != null) && (text.length() > 0)) {
if ((text.indexOf("[") >= 0) && (text.indexOf("]") > 0)) {
int startIndex = text.indexOf("[");
int endIndex = text.indexOf("]");
sb.append(text.substring(0, startIndex) + tableName + text.substring(endIndex + "]".length(), text.length()));
} else {
sb.append(text);
}
}
sb.append("</" + child.getName() + ">" + APM.LINE_SEP);
}
sb.append(" </generator>" + APM.LINE_SEP);
} else {
sb.append(" <generator class=\"" + uniqueKeyGenerator + "\" />" + APM.LINE_SEP);
}
sb.append("</id>" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param destinationTableName DOCUMENT ME!
* @param importedKeys DOCUMENT ME!
* @param importedKeysOrdered DOCUMENT ME!
* @param primaryKeyColumns DOCUMENT ME!
*/
private void processCompositeKey(StringBuffer sb,
String destinationTableName,
HashMap importedKeys,
ArrayList importedKeysOrdered,
ArrayList primaryKeyColumns) {
// check which primary key is only within this table and which ones point to another table
ArrayList onlyPrimaryKeyColumns = new ArrayList();
ArrayList primaryAndImportedKeyColumns = new ArrayList();
for (int i = 0; i < primaryKeyColumns.size(); i++) {
Element pkColumn = (Element) primaryKeyColumns.get(i);
if (importedKeys.containsKey(pkColumn.getAttributeValue(XMLTags.NAME))) {
primaryAndImportedKeyColumns.add(pkColumn);
} else {
onlyPrimaryKeyColumns.add(pkColumn);
}
}
// prepare imported key many-to-one fragments
HashMap importedKeysMap = new HashMap();
// imported keys to one or several parent tables... create a key-many-to-one element for each parent table
ArrayList parentTables = new ArrayList();
for (int i = 0; i < importedKeysOrdered.size(); i++) {
Element impKey = (Element) importedKeysOrdered.get(i);
if (!parentTables.contains(impKey.getAttributeValue(XMLTags.PKTABLE_NAME))) {
parentTables.add(impKey.getAttributeValue(XMLTags.PKTABLE_NAME));
}
}
for (int i = 0; i < parentTables.size(); i++) {
String parentTableName = (String) parentTables.get(i);
ArrayList childColumns = new ArrayList();
// retrieve the columns in right order which reference this parentTable
for (int j = 0; j < importedKeysOrdered.size(); j++) {
Element impKey = (Element) importedKeysOrdered.get(j);
if (impKey.getAttributeValue(XMLTags.PKTABLE_NAME).compareToIgnoreCase(parentTableName) == 0) {
childColumns.add(impKey);
}
}
StringBuffer fragment = new StringBuffer();
fragment.append(" <!-- bi-directional many-to-one association to " + parentTableName + " -->" + APM.LINE_SEP);
fragment.append(" <key-many-to-one" + APM.LINE_SEP);
fragment.append(" name=" + "\"" + parentTableName + "\"" + APM.LINE_SEP);
fragment.append(" class=" + "\"" + packageName + "." + parentTableName + "\"" + ">" + APM.LINE_SEP);
String columnNameIdentifier = null;
for (int j = 0; j < childColumns.size(); j++) {
Element col = (Element) childColumns.get(j);
fragment.append(" <column name=" + "\"" + col.getAttributeValue(XMLTags.FKCOLUMN_NAME) + "\"" + " />" + APM.LINE_SEP);
columnNameIdentifier = col.getAttributeValue(XMLTags.FKCOLUMN_NAME);
}
fragment.append(" </key-many-to-one>" + APM.LINE_SEP);
// take the latest, if there are several, fk_column_name as identifier for later correct insertion
importedKeysMap.put(columnNameIdentifier, fragment);
}
// write composite-id header
sb.append("<composite-id" + APM.LINE_SEP);
sb.append(" name=\"comp_id_" + destinationTableName + "\"" + APM.LINE_SEP);
sb.append(" class=\"" + packageName + "." + destinationTableName + "PK" + "\">" + APM.LINE_SEP);
// now the primary keys must be inserted in correct order
for (int indexOrder = 0; indexOrder < primaryKeyColumns.size(); indexOrder++) {
Element pkColumn = (Element) primaryKeyColumns.get(indexOrder);
// simple primary key column
if (onlyPrimaryKeyColumns.contains(pkColumn)) {
sb.append(" <key-property" + APM.LINE_SEP);
sb.append(" name=" + "\"" + pkColumn.getAttributeValue(XMLTags.NAME) + "\"" + APM.LINE_SEP);
sb.append(" column=" + "\"" + pkColumn.getAttributeValue(XMLTags.NAME) + "\"" + APM.LINE_SEP);
sb.append(" type=\"" + typeMapping.getJavaType(pkColumn.getAttributeValue(XMLTags.DATA_TYPE)) + "\"" + APM.LINE_SEP);
sb.append(" length=\"" + pkColumn.getAttributeValue(XMLTags.COLUMN_SIZE) + "\"" + "/>" + APM.LINE_SEP);
}
// imported key
else {
String columnName = pkColumn.getAttributeValue(XMLTags.NAME);
if (importedKeysMap.containsKey(columnName)) {
sb.append(importedKeysMap.get(columnName));
}
}
}
// write composite-id footer
sb.append("</composite-id>" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param indexes DOCUMENT ME!
* @param column DOCUMENT ME!
*/
private void processNormalColumn(StringBuffer sb,
HashMap indexes,
Element column) {
sb.append("<property");
sb.append(" name=\"" + column.getAttributeValue(XMLTags.NAME) + "\"");
sb.append(" type=\"" + typeMapping.getJavaType(column.getAttributeValue(XMLTags.DATA_TYPE)) + "\"");
sb.append(">" + APM.LINE_SEP);
sb.append(" <column" + APM.LINE_SEP);
sb.append(" name=\"" + column.getAttributeValue(XMLTags.NAME) + "\"" + APM.LINE_SEP);
sb.append(" length=\"" + column.getAttributeValue(XMLTags.COLUMN_SIZE) + "\"" + APM.LINE_SEP);
// check if not null
if (column.getAttributeValue(XMLTags.NULLABLE).compareTo("false") == 0) {
sb.append(" not-null=\"" + "true" + "\"" + APM.LINE_SEP);
}
// check for uniqueness and indexes
if (indexes.containsKey(column.getAttributeValue(XMLTags.NAME))) {
Element index = (Element) indexes.get(column.getAttributeValue(XMLTags.NAME));
// check uniqueness
if ((index.getAttributeValue(XMLTags.NON_UNIQUE) != null) && (index.getAttributeValue(XMLTags.NON_UNIQUE).compareTo("0") == 0)) {
sb.append(" unique=\"true\"" + APM.LINE_SEP);
}
// add index name
if ((index.getAttributeValue(XMLTags.INDEX_NAME) != null) && (index.getAttributeValue(XMLTags.INDEX_NAME).length() > 0)) {
sb.append(" index=\"" + index.getAttributeValue(XMLTags.INDEX_NAME) + "\"" + APM.LINE_SEP);
}
}
sb.append(" />" + APM.LINE_SEP);
sb.append("</property>" + APM.LINE_SEP);
}
/**
* Imported Keys are appended at the end of a table, given by hbm2java Tool, independent of hbm column order An imported key can be a reference
* to a single primary key or compound key of another table
*
* @param sb DOCUMENT ME!
* @param mapImportedKeyElements DOCUMENT ME!
* @param listImportedKeyColumns DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void processImportedKeys(StringBuffer sb,
HashMap mapImportedKeyElements,
ArrayList listImportedKeyColumns) throws MissingElementException {
// find out which columns are imported keys pointing to a compound key - or primary key
HashMap mapImportedTables = new HashMap();
ArrayList listImportedTablesOrdered = new ArrayList();
for (int i = 0; i < listImportedKeyColumns.size(); i++) {
Element columnElement = (Element) listImportedKeyColumns.get(i);
Element impElement = (Element) mapImportedKeyElements.get(columnElement.getAttributeValue(XMLTags.NAME));
String referencedTableName = impElement.getAttributeValue(XMLTags.PKTABLE_NAME);
if (!listImportedTablesOrdered.contains(referencedTableName)) {
listImportedTablesOrdered.add(referencedTableName);
}
if (!mapImportedTables.containsKey(referencedTableName)) {
ArrayList list = new ArrayList();
list.add(impElement);
mapImportedTables.put(referencedTableName, list);
} else {
ArrayList list = (ArrayList) mapImportedTables.get(referencedTableName);
list.add(impElement);
}
}
for (int i = 0; i < listImportedTablesOrdered.size(); i++) {
String referencedTableName = (String) listImportedTablesOrdered.get(i);
ArrayList listImpElements = (ArrayList) mapImportedTables.get(referencedTableName);
if (listImpElements.size() == 1) {
Element impElement = (Element) listImpElements.get(0);
Element columnElement = model.getDestinationColumn(impElement.getAttributeValue(XMLTags.FKTABLE_NAME), impElement.getAttributeValue(XMLTags.FKCOLUMN_NAME));
processSingleImportedKey(sb, impElement, columnElement);
} else {
processCompositeImportedKey(sb, listImpElements);
}
}
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param impKey DOCUMENT ME!
* @param column DOCUMENT ME!
*/
private void processSingleImportedKey(StringBuffer sb,
Element impKey,
Element column) {
sb.append("<many-to-one");
sb.append(" name=\"" + impKey.getAttributeValue(XMLTags.PKTABLE_NAME).toLowerCase() + MANY_TO_ONE_REF_EXTENSION + "\"");
sb.append(" class=\"" + packageName + "." + impKey.getAttributeValue(XMLTags.PKTABLE_NAME) + "\"");
int deleteRule = Integer.parseInt(impKey.getAttributeValue(XMLTags.DELETE_RULE));
processImportDeleteRule(sb, deleteRule);
sb.append(" outer-join=\"" + outerJoin + "\"");
if (column.getAttributeValue(XMLTags.NULLABLE).compareTo("false") == 0) {
sb.append(" not-null=\"" + "true" + "\"");
}
sb.append(">" + APM.LINE_SEP);
sb.append(" <column name=\"" + impKey.getAttributeValue(XMLTags.FKCOLUMN_NAME) + "\"" + " />" + APM.LINE_SEP);
sb.append("</many-to-one>" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param impKeys DOCUMENT ME!
*
* @throws MissingElementException DOCUMENT ME!
*/
private void processCompositeImportedKey(StringBuffer sb,
ArrayList impKeys) throws MissingElementException {
// Retrieve basic information
Element impElement = (Element) impKeys.get(0);
Element columnElement = model.getDestinationColumn(impElement.getAttributeValue(XMLTags.FKTABLE_NAME), impElement.getAttributeValue(XMLTags.FKCOLUMN_NAME));
String importedTableName = impElement.getAttributeValue(XMLTags.PKTABLE_NAME);
String deleteRuleString = impElement.getAttributeValue(XMLTags.DELETE_RULE);
sb.append("<many-to-one");
sb.append(" name=\"" + importedTableName.toLowerCase() + MANY_TO_ONE_REF_EXTENSION + "\"");
sb.append(" class=\"" + packageName + "." + importedTableName + "\"");
int deleteRule = Integer.parseInt(deleteRuleString);
processImportDeleteRule(sb, deleteRule);
sb.append(" outer-join=\"" + outerJoin + "\"");
if (columnElement.getAttributeValue(XMLTags.NULLABLE).compareTo("false") == 0) {
sb.append(" not-null=\"" + "true" + "\"");
}
sb.append(">" + APM.LINE_SEP);
for (int i = 0; i < impKeys.size(); i++) {
Element impKey = (Element) impKeys.get(i);
sb.append(" <column name=\"" + impKey.getAttributeValue(XMLTags.FKCOLUMN_NAME) + "\"" + " />" + APM.LINE_SEP);
}
sb.append("</many-to-one>" + APM.LINE_SEP);
}
/**
* DOCUMENT ME!
*
* @param sb DOCUMENT ME!
* @param deleteRule DOCUMENT ME!
*/
private void processImportDeleteRule(StringBuffer sb,
int deleteRule) {
switch (deleteRule) {
case DatabaseMetaData.importedKeyNoAction:
sb.append(" cascade=\"none\"");
break;
case DatabaseMetaData.importedKeyRestrict:
sb.append(" cascade=\"none\"");
break;
case DatabaseMetaData.importedKeyCascade:
sb.append(" cascade=\"all\"");
break;
case DatabaseMetaData.importedKeySetNull:
sb.append(" cascade=\"all\"");
break;
case DatabaseMetaData.importedKeySetDefault:
sb.append(" cascade=\"all\"");
break;
}
}
/**
* DOCUMENT ME!
*
* @param expKey DOCUMENT ME!
*/
private void processExportedKey(Element expKey) {
sb.append("<set");
// the exported key name must be different than the foreign key table name as other object may already have a reference called the same
sb.append(" name=\"" + expKey.getAttributeValue(XMLTags.FKTABLE_NAME).toLowerCase() + "s" + "\"");
sb.append(" lazy=\"" + lazy + "\"");
sb.append(" inverse=\"" + inverse + "\"");
int deleteRule = Integer.parseInt(expKey.getAttributeValue(XMLTags.DELETE_RULE));
switch (deleteRule) {
case DatabaseMetaData.importedKeyNoAction:
sb.append(" cascade=\"none\"");
break;
case DatabaseMetaData.importedKeyRestrict:
sb.append(" cascade=\"none\"");
break;
case DatabaseMetaData.importedKeyCascade:
sb.append(" cascade=\"all\"");
break;
case DatabaseMetaData.importedKeySetNull:
sb.append(" cascade=\"all\"");
break;
case DatabaseMetaData.importedKeySetDefault:
sb.append(" cascade=\"all\"");
break;
}
sb.append(">" + APM.LINE_SEP);
sb.append(" <key");
sb.append(" column=\"" + expKey.getAttributeValue(XMLTags.FKCOLUMN_NAME) + "\"");
sb.append(" />" + APM.LINE_SEP);
sb.append(" <one-to-many");
sb.append(" class=\"" + packageName + "." + expKey.getAttributeValue(XMLTags.FKTABLE_NAME) + "\"");
sb.append(" />" + APM.LINE_SEP);
sb.append("</set>" + APM.LINE_SEP);
}
}