0001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
0002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
0003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
0005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
0006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
0008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
0011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
0012: // POSSIBILITY OF SUCH DAMAGE.
0013: //
0014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
0015: package com.metaboss.sdlctools.services.codegeneration.storageimplementationgenerator.relational;
0016:
0017: import java.io.File;
0018: import java.io.FileWriter;
0019: import java.io.IOException;
0020: import java.io.PrintWriter;
0021: import java.io.Writer;
0022: import java.util.ArrayList;
0023: import java.util.Arrays;
0024: import java.util.Collection;
0025: import java.util.HashSet;
0026: import java.util.Iterator;
0027: import java.util.List;
0028: import java.util.Map;
0029: import java.util.Properties;
0030: import java.util.Set;
0031:
0032: import javax.jmi.reflect.JmiException;
0033:
0034: import org.apache.commons.logging.Log;
0035: import org.apache.commons.logging.LogFactory;
0036:
0037: import com.metaboss.enterprise.bs.BSException;
0038: import com.metaboss.enterprise.bs.BSServiceProviderException;
0039: import com.metaboss.enterprise.datatypes.DataTypeTranslationMetadata;
0040: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
0041: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataTypeUtils;
0042: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.TypeTemplate;
0043: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Enterprise;
0044: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Association;
0045: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.AssociationRole;
0046: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
0047: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
0048: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
0049: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.PrimaryKeyElement;
0050: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainRelationalStorageDefinition;
0051: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalAssociationTable;
0052: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTable;
0053: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableAttributeColumn;
0054: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableReferenceColumn;
0055: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalReferenceTable;
0056: import com.metaboss.sdlctools.models.metabossmodel.statemachinemodel.State;
0057: import com.metaboss.sdlctools.services.codegeneration.CommonUtil;
0058: import com.metaboss.sdlctools.services.codegeneration.CopyrightUtils;
0059: import com.metaboss.util.DirectoryUtils;
0060: import com.metaboss.util.StringUtils;
0061:
0062: /** Generator of the persistence layer implementation based on oracle DBMS */
0063: public class DBScriptsGeneratorBase {
0064: // Commons Logging instance.
0065: private static final Log sLogger = LogFactory
0066: .getLog(DBScriptsGeneratorBase.class);
0067: private DataBaseMetaData mDataBaseMetaData = null;
0068:
0069: /** Hide default constructor */
0070: private DBScriptsGeneratorBase() {
0071: }
0072:
0073: /** The only publicly available constructor */
0074: public DBScriptsGeneratorBase(DataBaseMetaData pDataBaseMetaData) {
0075: mDataBaseMetaData = pDataBaseMetaData;
0076: }
0077:
0078: public void generateDBScripts(String pSourceRootDir,
0079: DomainRelationalStorageDefinition pDomainStorage)
0080: throws BSException {
0081: String lImplementationDir = pSourceRootDir;
0082: DirectoryUtils.ensureThereIsDirectory(lImplementationDir);
0083:
0084: // Generate the script which cleans up the whole lot
0085: generateDeleteAllScript(lImplementationDir, pDomainStorage);
0086: // First generate the script which creates the database from scratch
0087: generateCreateFromScratchScript(lImplementationDir,
0088: pDomainStorage);
0089: }
0090:
0091: // Generates the script which allows to create database from scratch
0092: protected void generateDeleteAllScript(String pImplementationDir,
0093: DomainRelationalStorageDefinition pDomainStorage)
0094: throws BSException {
0095: FileWriter lFileWriter = null;
0096: PrintWriter lWriter = null;
0097: // Generate services interface
0098: try {
0099: Domain lDomain = pDomainStorage.getDomain();
0100: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0101: .getSystem();
0102: Enterprise lEnterprise = lSystem.getEnterprise();
0103: // Setup typetemplates necessary for the datatypes
0104: TypeTemplate lEnumerableValueTypeTemplate = lEnterprise
0105: .getDesignLibrary().getDataDictionary("core")
0106: .getTypeTemplate("EnumerableValueField");
0107: String lScriptFileName = pImplementationDir
0108: + File.separator + "DBScript_"
0109: + lEnterprise.getName() + "_" + lSystem.getName()
0110: + "_" + lDomain.getName() + "_DeleteAll_"
0111: + pDomainStorage.getTechnology().getName() + ".sql";
0112: sLogger
0113: .info("Generating " + lScriptFileName
0114: + " script...");
0115:
0116: lWriter = new PrintWriter(lFileWriter = new FileWriter(
0117: lScriptFileName));
0118: CopyrightUtils.writeCopyrightToGeneratedSQLFile(lWriter);
0119: // Delete in the reverse order to creation
0120:
0121: // Work on associations
0122: {
0123: Collection lAssociations = lDomain.getAssociations();
0124: // First delete plural association constraints if we need to
0125: if (mDataBaseMetaData.needGenerateDropConstraints()) {
0126: for (Iterator lAssociationsIterator = lAssociations
0127: .iterator(); lAssociationsIterator
0128: .hasNext();) {
0129: Association lAssociation = (Association) lAssociationsIterator
0130: .next();
0131: writeStatements(
0132: lWriter,
0133: generateAssociationConstraintsDeletionStatement(
0134: lAssociation, pDomainStorage));
0135: }
0136: }
0137: // Second delete plural association tables
0138: for (Iterator lAssociationsIterator = lAssociations
0139: .iterator(); lAssociationsIterator.hasNext();) {
0140: Association lAssociation = (Association) lAssociationsIterator
0141: .next();
0142: writeStatements(lWriter,
0143: generateAssociationTableDeletionStatement(
0144: lAssociation, pDomainStorage));
0145: }
0146: }
0147:
0148: // Work on entities
0149: {
0150: Collection lEntities = lDomain.getEntities();
0151: // First delete entity constraints if we need to
0152: if (mDataBaseMetaData.needGenerateDropConstraints()) {
0153: for (Iterator lEntitiesIterator = lEntities
0154: .iterator(); lEntitiesIterator.hasNext();) {
0155: Entity lEntity = (Entity) lEntitiesIterator
0156: .next();
0157: writeStatements(
0158: lWriter,
0159: generateEntityConstraintsDeletionStatement(
0160: lEntity, pDomainStorage));
0161: }
0162: }
0163: // Second delete entity tables
0164: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0165: .hasNext();) {
0166: Entity lEntity = (Entity) lEntitiesIterator.next();
0167: writeStatements(lWriter,
0168: generateEntityTableDeletionStatement(
0169: lEntity, pDomainStorage));
0170: }
0171: }
0172:
0173: // Work on enumerable types
0174: {
0175: // For all enumerable types used in this domain, generate the table and populate it with enumerable types.
0176: Collection lEntities = lDomain.getEntities();
0177: // Generate all state machine table deletion statements and all enumerable types
0178: Set lAlreadyProcessedDataTypes = new HashSet();
0179: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0180: .hasNext();) {
0181: Entity lEntity = (Entity) lEntitiesIterator.next();
0182: if (lEntity.getStateMachine() != null)
0183: writeStatements(
0184: lWriter,
0185: generateStateReferenceTableDeletionStatement(
0186: lDomain, lEntity,
0187: pDomainStorage));
0188: Collection lAttributes = lEntity.getAttributes();
0189: for (Iterator lAttributesIterator = lAttributes
0190: .iterator(); lAttributesIterator.hasNext();) {
0191: Attribute lAttribute = (Attribute) lAttributesIterator
0192: .next();
0193: DataType lAttributeDatatype = lAttribute
0194: .getDataType();
0195: if (!lAlreadyProcessedDataTypes
0196: .contains(lAttributeDatatype)) {
0197: TypeTemplate lTypetemplate = lAttributeDatatype
0198: .getTypetemplate();
0199: if (lTypetemplate != null
0200: && lTypetemplate
0201: .equals(lEnumerableValueTypeTemplate)) {
0202: writeStatements(
0203: lWriter,
0204: generateReferenceTableDeletionStatement(
0205: lDomain,
0206: lAttributeDatatype,
0207: pDomainStorage));
0208: lAlreadyProcessedDataTypes
0209: .add(lAttributeDatatype);
0210: }
0211: }
0212: }
0213: }
0214: }
0215: // Work on schema
0216: writeStatements(lWriter, generateSchemaDeletionStatement(
0217: lDomain, pDomainStorage));
0218:
0219: sLogger.info("Done generating " + lScriptFileName
0220: + " script");
0221: } catch (IOException e) {
0222: throw new BSServiceProviderException(e);
0223: } catch (JmiException e) {
0224: throw new BSServiceProviderException(e);
0225: } finally {
0226: if (lWriter != null) {
0227: lWriter.flush();
0228: lWriter.close();
0229: }
0230: if (lFileWriter != null) {
0231: try {
0232: lFileWriter.flush();
0233: } catch (IOException e) {
0234: // Ignore
0235: }
0236: try {
0237: lFileWriter.close();
0238: } catch (IOException e) {
0239: // Ignore
0240: }
0241: }
0242: }
0243: }
0244:
0245: // Generates the script which allows to create database from scratch
0246: protected void generateCreateFromScratchScript(
0247: String pImplementationDir,
0248: DomainRelationalStorageDefinition pDomainStorage)
0249: throws BSException {
0250: FileWriter lFileWriter = null;
0251: PrintWriter lWriter = null;
0252: // Generate services interface
0253: try {
0254: Domain lDomain = pDomainStorage.getDomain();
0255: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
0256: .getSystem();
0257: Enterprise lEnterprise = lSystem.getEnterprise();
0258: // Setup typetemplates necessary for the datatypes
0259: TypeTemplate lEnumerableValueTypeTemplate = lEnterprise
0260: .getDesignLibrary().getDataDictionary("core")
0261: .getTypeTemplate("EnumerableValueField");
0262: String lScriptFileName = pImplementationDir
0263: + File.separator + "DBScript_"
0264: + lEnterprise.getName() + "_" + lSystem.getName()
0265: + "_" + lDomain.getName() + "_CreateFromScratch_"
0266: + pDomainStorage.getTechnology().getName() + ".sql";
0267: sLogger
0268: .info("Generating " + lScriptFileName
0269: + " script...");
0270:
0271: lWriter = new PrintWriter(lFileWriter = new FileWriter(
0272: lScriptFileName));
0273: CopyrightUtils.writeCopyrightToGeneratedSQLFile(lWriter);
0274: // Work on schema
0275: writeStatements(lWriter, generateSchemaCreationStatement(
0276: lDomain, pDomainStorage));
0277: // Work on enumerable types. They could be of two kinds :
0278: // pure enumerable types and states from the state machine
0279: {
0280: // For all enumerable types used in this domain, generate the table and populate it with enumerable types.
0281: Collection lEntities = lDomain.getEntities();
0282: // Generate all state machine table deletion statements and all enumerable types
0283: Set lAlreadyProcessedDataTypes = new HashSet();
0284: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0285: .hasNext();) {
0286: Entity lEntity = (Entity) lEntitiesIterator.next();
0287: if (lEntity.getStateMachine() != null)
0288: writeStatements(
0289: lWriter,
0290: generateStateReferenceTableCreationStatement(
0291: lDomain, lEntity,
0292: pDomainStorage));
0293: Collection lAttributes = lEntity.getAttributes();
0294: for (Iterator lAttributesIterator = lAttributes
0295: .iterator(); lAttributesIterator.hasNext();) {
0296: Attribute lAttribute = (Attribute) lAttributesIterator
0297: .next();
0298: DataType lAttributeDatatype = lAttribute
0299: .getDataType();
0300: if (!lAlreadyProcessedDataTypes
0301: .contains(lAttributeDatatype)) {
0302: TypeTemplate lTypetemplate = lAttributeDatatype
0303: .getTypetemplate();
0304: if (lTypetemplate != null
0305: && lTypetemplate
0306: .equals(lEnumerableValueTypeTemplate)) {
0307: writeStatements(
0308: lWriter,
0309: generateReferenceTableCreationStatement(
0310: lDomain,
0311: lAttributeDatatype,
0312: pDomainStorage));
0313: lAlreadyProcessedDataTypes
0314: .add(lAttributeDatatype);
0315: }
0316: }
0317: }
0318: }
0319: }
0320:
0321: // Work on entities
0322: {
0323: Collection lEntities = lDomain.getEntities();
0324: // First delete entity constraints
0325: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0326: .hasNext();) {
0327: Entity lEntity = (Entity) lEntitiesIterator.next();
0328: writeStatements(lWriter,
0329: generateEntityTableCreationStatement(
0330: lEntity, pDomainStorage));
0331: }
0332: // Second generate entity constraints
0333: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0334: .hasNext();) {
0335: Entity lEntity = (Entity) lEntitiesIterator.next();
0336: writeStatements(lWriter,
0337: generateEntityConstraintsCreationStatement(
0338: lEntity, pDomainStorage));
0339: }
0340: }
0341: // Work on associations
0342: {
0343: // First generate plural association tables
0344: Collection lAssociations = lDomain.getAssociations();
0345: // First delete plural association constraints
0346: for (Iterator lAssociationsIterator = lAssociations
0347: .iterator(); lAssociationsIterator.hasNext();) {
0348: Association lAssociation = (Association) lAssociationsIterator
0349: .next();
0350: writeStatements(lWriter,
0351: generateAssociationTableCreationStatement(
0352: lAssociation, pDomainStorage));
0353: }
0354:
0355: // Second generate plural associations constraints
0356: for (Iterator lAssociationsIterator = lAssociations
0357: .iterator(); lAssociationsIterator.hasNext();) {
0358: Association lAssociation = (Association) lAssociationsIterator
0359: .next();
0360: writeStatements(
0361: lWriter,
0362: generateAssociationConstraintsCreationStatement(
0363: lAssociation, pDomainStorage));
0364: }
0365: }
0366: sLogger.info("Done generating " + lScriptFileName
0367: + " script");
0368: } catch (IOException e) {
0369: throw new BSException(e);
0370: } catch (JmiException e) {
0371: throw new BSServiceProviderException(e);
0372: } finally {
0373: if (lWriter != null) {
0374: lWriter.flush();
0375: lWriter.close();
0376: }
0377: if (lFileWriter != null) {
0378: try {
0379: lFileWriter.flush();
0380: } catch (IOException e) {
0381: // Ignore
0382: }
0383: try {
0384: lFileWriter.close();
0385: } catch (IOException e) {
0386: // Ignore
0387: }
0388: }
0389: }
0390: }
0391:
0392: /* Generates database domain tables from scratch */
0393: protected String[] generateSchemaDeletionStatement(Domain pDomain,
0394: DomainRelationalStorageDefinition pDomainStorage)
0395: throws BSException {
0396: // Build statements on a fly
0397: return new String[] { "DROP TABLE " + "idregistry;", };
0398: }
0399:
0400: /* Generates database domain tables from scratch */
0401: protected String[] generateSchemaCreationStatement(Domain pDomain,
0402: DomainRelationalStorageDefinition pDomainStorage)
0403: throws BSException {
0404: Properties lTableNameProperties = new Properties();
0405: lTableNameProperties.setProperty("maxsize", "40");
0406: Properties lTableAliasProperties = new Properties();
0407: lTableAliasProperties.setProperty("maxsize", "12");
0408: Properties lNextSessionIdProperties = new Properties();
0409:
0410: List lStatements = new ArrayList();
0411: lStatements
0412: .add("CREATE TABLE idregistry ("
0413: + mDataBaseMetaData
0414: .suggestColumnDefinition(
0415: "table_name",
0416: DataTypeTranslationMetadata.SQL_VARCHAR,
0417: lTableNameProperties, true,
0418: false)
0419: + ","
0420: + mDataBaseMetaData
0421: .suggestColumnDefinition(
0422: "table_alias",
0423: DataTypeTranslationMetadata.SQL_VARCHAR,
0424: lTableAliasProperties, true,
0425: false)
0426: + ","
0427: + mDataBaseMetaData.suggestColumnDefinition(
0428: "next_available_session_id",
0429: DataTypeTranslationMetadata.SQL_BIGINT,
0430: lNextSessionIdProperties, true, false)
0431: + ", CONSTRAINT pkidregistry PRIMARY KEY (table_name), CONSTRAINT ukidregistry UNIQUE (table_alias) );");
0432: if (mDataBaseMetaData.needGenerateTableComments())
0433: lStatements
0434: .add("COMMENT ON TABLE idregistry IS 'Contains various per-table values used in middleware implementation. It is very much implementation specific and does not represent any part of the domain model.';");
0435: if (mDataBaseMetaData.needGenerateTableColumnComments()) {
0436: lStatements
0437: .add("COMMENT ON COLUMN idregistry.table_name IS 'The name of the table associated with this registry record.';");
0438: lStatements
0439: .add("COMMENT ON COLUMN idregistry.table_alias IS 'The alias of the table. Used in various queries as well as in record id generation';");
0440: lStatements
0441: .add("COMMENT ON COLUMN idregistry.next_available_session_id IS 'Absolute count (since schema creation) of the middleware sessions that accessed this table. Used at middleware by unique record instance id generator.';");
0442: }
0443: return (String[]) lStatements.toArray(new String[lStatements
0444: .size()]);
0445: }
0446:
0447: /* Generates database domain tables from scratch */
0448: protected String[] generateEntityTableDeletionStatement(
0449: Entity pEntity,
0450: DomainRelationalStorageDefinition pDomainStorage)
0451: throws BSException {
0452: StringBuffer pStatementBuffer = new StringBuffer();
0453: try {
0454: RelationalEntityTable lEntityTable = pDomainStorage
0455: .getEntityTable(pEntity);
0456: String lEntityTableName = lEntityTable.getNameOverride();
0457: if (lEntityTableName == null
0458: || lEntityTableName.length() == 0)
0459: lEntityTableName = lEntityTable.getNameSuggestion();
0460:
0461: // Build statement on a fly
0462: pStatementBuffer.append("DROP TABLE ");
0463: pStatementBuffer.append(lEntityTableName);
0464: pStatementBuffer.append(";");
0465: return new String[] { pStatementBuffer.toString() };
0466: } catch (JmiException e) {
0467: throw new BSServiceProviderException(e);
0468: }
0469: }
0470:
0471: /* Generates database domain tables from scratch */
0472: protected String[] generateReferenceTableDeletionStatement(
0473: Domain pDomain, DataType pDatatype,
0474: DomainRelationalStorageDefinition pDomainStorage)
0475: throws BSException {
0476:
0477: StringBuffer pStatementBuffer = new StringBuffer();
0478: try {
0479: RelationalReferenceTable lReferenceTable = pDomainStorage
0480: .getReferenceTable(pDatatype);
0481: String lReferenceTableName = lReferenceTable
0482: .getNameOverride();
0483: if (lReferenceTableName == null
0484: || lReferenceTableName.length() == 0)
0485: lReferenceTableName = lReferenceTable
0486: .getNameSuggestion();
0487:
0488: // Build statement on a fly
0489: pStatementBuffer.append("DROP TABLE ");
0490: pStatementBuffer.append(lReferenceTableName);
0491: pStatementBuffer.append(";");
0492: return new String[] { pStatementBuffer.toString() };
0493: } catch (JmiException e) {
0494: throw new BSServiceProviderException(e);
0495: }
0496: }
0497:
0498: /* Generates database domain tables from scratch */
0499: protected String[] generateEntityTableCreationStatement(
0500: Entity pEntity,
0501: DomainRelationalStorageDefinition pDomainStorage)
0502: throws BSException {
0503: try {
0504:
0505: Collection lAttributes = pEntity.getAttributes();
0506: Collection lReferences = pEntity.getReferences();
0507: AssociationRole lOwnerReference = pEntity
0508: .getOwnerReference();
0509:
0510: RelationalEntityTable lEntityTable = pDomainStorage
0511: .getEntityTable(pEntity);
0512: String lEntityTableName = lEntityTable.getNameOverride();
0513: if (lEntityTableName == null
0514: || lEntityTableName.length() == 0)
0515: lEntityTableName = lEntityTable.getNameSuggestion();
0516: String lInstanceIdColumnName = lEntityTable
0517: .getInstanceIdColumnNameOverride();
0518: if (lInstanceIdColumnName == null
0519: || lInstanceIdColumnName.length() == 0)
0520: lInstanceIdColumnName = lEntityTable
0521: .getInstanceIdColumnNameSuggestion();
0522: String lEntityTableAlias = lEntityTable.getTableAlias();
0523:
0524: ArrayList lStatements = new ArrayList();
0525: // Work on the table creation statement
0526: {
0527: // Build statement on a fly
0528: StringBuffer pStatementBuffer = new StringBuffer();
0529: pStatementBuffer.append("CREATE TABLE ");
0530: pStatementBuffer.append(lEntityTableName);
0531: pStatementBuffer.append(" (");
0532: // System attributes first
0533: pStatementBuffer.append(mDataBaseMetaData
0534: .suggestColumnDefinition(lInstanceIdColumnName,
0535: pEntity.getInstanceIdDataType(), true,
0536: false));
0537: if (pEntity.isModifiable()) {
0538: String lVersionIdColumnName = lEntityTable
0539: .getVersionIdColumnNameOverride();
0540: if (lVersionIdColumnName == null
0541: || lVersionIdColumnName.length() == 0)
0542: lVersionIdColumnName = lEntityTable
0543: .getVersionIdColumnNameSuggestion();
0544: pStatementBuffer.append(",");
0545: pStatementBuffer.append(mDataBaseMetaData
0546: .suggestColumnDefinition(
0547: lVersionIdColumnName, pEntity
0548: .getVersionIdDataType(),
0549: true, false));
0550: }
0551: if (pEntity.getStateMachine() != null) {
0552: String lStateColumnName = lEntityTable
0553: .getStateColumnNameOverride();
0554: if (lStateColumnName == null
0555: || lStateColumnName.length() == 0)
0556: lStateColumnName = lEntityTable
0557: .getStateColumnNameSuggestion();
0558: pStatementBuffer.append(",");
0559: pStatementBuffer.append(mDataBaseMetaData
0560: .suggestColumnDefinition(lStateColumnName,
0561: pEntity.getStateDataType(), true,
0562: true));
0563: }
0564: for (Iterator lAttributesIterator = lAttributes
0565: .iterator(); lAttributesIterator.hasNext();) {
0566: Attribute lAttribute = (Attribute) lAttributesIterator
0567: .next();
0568: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
0569: .getAttributeColumn(lAttribute);
0570: String lAttributeColumnName = lRelationalEntityTableAttribute
0571: .getColumnNameOverride();
0572: if (lAttributeColumnName == null
0573: || lAttributeColumnName.length() == 0)
0574: lAttributeColumnName = lRelationalEntityTableAttribute
0575: .getColumnNameSuggestion();
0576: pStatementBuffer.append(",");
0577: pStatementBuffer.append(mDataBaseMetaData
0578: .suggestColumnDefinition(
0579: lAttributeColumnName, lAttribute
0580: .getDataType(), !lAttribute
0581: .isOptional(), false));
0582: }
0583: // Deal with associations
0584: for (Iterator lReferencesIterator = lReferences
0585: .iterator(); lReferencesIterator.hasNext();) {
0586: AssociationRole lReference = (AssociationRole) lReferencesIterator
0587: .next();
0588: // Reference column is only necessary if this entity has a reference
0589: if (CommonUtil.doesEntityStoreReference(lReference)) {
0590: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
0591: .getReferenceColumn(lReference);
0592: String lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0593: .getColumnNameOverride();
0594: if (lAssociationRoleInstanceIdColumnName == null
0595: || lAssociationRoleInstanceIdColumnName
0596: .length() == 0)
0597: lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0598: .getColumnNameSuggestion();
0599:
0600: pStatementBuffer.append(",");
0601: //TODO: For now will only insert mandatory (not null) constraint for owner entity. For the mandatory associations we will have to come back and think how to do it
0602: pStatementBuffer
0603: .append(mDataBaseMetaData
0604: .suggestColumnDefinition(
0605: lAssociationRoleInstanceIdColumnName,
0606: lReference
0607: .getEntity()
0608: .getInstanceIdDataType(),
0609: lReference
0610: .equals(lOwnerReference),
0611: true));
0612: }
0613: }
0614: pStatementBuffer.append(",CONSTRAINT ");
0615:
0616: String lPrimaryKeyConstraintName = lEntityTable
0617: .getPrimaryKeyConstraintNameOverride();
0618: if (lPrimaryKeyConstraintName == null
0619: || lPrimaryKeyConstraintName.length() == 0)
0620: lPrimaryKeyConstraintName = lEntityTable
0621: .getPrimaryKeyConstraintNameSuggestion();
0622: pStatementBuffer.append(lPrimaryKeyConstraintName);
0623: pStatementBuffer.append(" PRIMARY KEY (");
0624: pStatementBuffer.append(lInstanceIdColumnName);
0625: pStatementBuffer.append(")");
0626: // Cater for 'Logical' primary key if there is one
0627: // For now only cater for the simple primary key - the key where
0628: // every element of the key is part of this entity table. This does not cater for
0629: // parts of primary key scattered along inheritance tree, we will need to
0630: // cater for it with some sort of trigger (Oracle check constraints are not
0631: // allowed to address columns in the other tables)
0632: if (pEntity.getPrimaryKeyElements().size() > 0) {
0633: Map lPrimaryKeyElementsPerTableMap = SQLJDBCUtil
0634: .getPrimaryKeyElementsPerTableMap(pEntity);
0635: if (lPrimaryKeyElementsPerTableMap.size() == 1
0636: && lPrimaryKeyElementsPerTableMap
0637: .containsKey(pEntity)) {
0638: pStatementBuffer.append(",CONSTRAINT ");
0639: String lNaturalPrimaryKeyConstraintName = lEntityTable
0640: .getNaturalPrimaryKeyConstraintNameOverride();
0641: if (lNaturalPrimaryKeyConstraintName == null
0642: || lNaturalPrimaryKeyConstraintName
0643: .length() == 0)
0644: lNaturalPrimaryKeyConstraintName = lEntityTable
0645: .getNaturalPrimaryKeyConstraintNameSuggestion();
0646: pStatementBuffer
0647: .append(lNaturalPrimaryKeyConstraintName);
0648: pStatementBuffer.append(" UNIQUE (");
0649: boolean lNeedComma = false;
0650: Collection lPrimaryKeyElements = pEntity
0651: .getPrimaryKeyElements();
0652: for (Iterator lPrimaryKeyElementsIterator = lPrimaryKeyElements
0653: .iterator(); lPrimaryKeyElementsIterator
0654: .hasNext();) {
0655: PrimaryKeyElement lPrimaryKeyElement = (PrimaryKeyElement) lPrimaryKeyElementsIterator
0656: .next();
0657: if (lNeedComma)
0658: pStatementBuffer.append(", ");
0659: else
0660: lNeedComma = true;
0661: if (lPrimaryKeyElement instanceof Attribute) {
0662: Attribute lAttribute = (Attribute) lPrimaryKeyElement;
0663: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
0664: .getAttributeColumn(lAttribute);
0665: String lAttributeColumnName = lRelationalEntityTableAttribute
0666: .getColumnNameOverride();
0667: if (lAttributeColumnName == null
0668: || lAttributeColumnName
0669: .length() == 0)
0670: lAttributeColumnName = lRelationalEntityTableAttribute
0671: .getColumnNameSuggestion();
0672: pStatementBuffer
0673: .append(lAttributeColumnName);
0674: }
0675: if (lPrimaryKeyElement instanceof AssociationRole) {
0676: AssociationRole lAssociationRole = (AssociationRole) lPrimaryKeyElement;
0677: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
0678: .getReferenceColumn(lAssociationRole);
0679: String lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0680: .getColumnNameOverride();
0681: if (lAssociationRoleInstanceIdColumnName == null
0682: || lAssociationRoleInstanceIdColumnName
0683: .length() == 0)
0684: lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
0685: .getColumnNameSuggestion();
0686: pStatementBuffer
0687: .append(lAssociationRoleInstanceIdColumnName);
0688: }
0689: }
0690: pStatementBuffer.append(")");
0691: }
0692: }
0693: pStatementBuffer.append(");");
0694: lStatements.add(pStatementBuffer.toString());
0695: }
0696:
0697: // Now create the idregistry insert
0698: {
0699: // Build statement on a fly
0700: StringBuffer pStatementBuffer = new StringBuffer();
0701: pStatementBuffer.append("INSERT INTO ");
0702: pStatementBuffer
0703: .append("idregistry (table_name, table_alias, next_available_session_id) VALUES('");
0704: pStatementBuffer.append(lEntityTableName);
0705: pStatementBuffer.append("','");
0706: pStatementBuffer.append(lEntityTableAlias);
0707: pStatementBuffer.append("',1);");
0708: lStatements.add(pStatementBuffer.toString());
0709: }
0710:
0711: // Generate table level comments
0712: if (mDataBaseMetaData.needGenerateTableComments())
0713: lStatements.addAll(Arrays.asList(generateTableComment(
0714: pEntity, pDomainStorage)));
0715:
0716: // Generate table level comments
0717: if (mDataBaseMetaData.needGenerateTableColumnComments())
0718: lStatements.addAll(Arrays
0719: .asList(generateTableColumnComments(pEntity,
0720: pDomainStorage)));
0721:
0722: return (String[]) lStatements
0723: .toArray(new String[lStatements.size()]);
0724: } catch (JmiException e) {
0725: throw new BSServiceProviderException(e);
0726: }
0727: }
0728:
0729: // Generates reference datat tables from scratch */
0730: protected String[] generateReferenceTableCreationStatement(
0731: Domain pDomain, DataType pReferenceDatatype,
0732: DomainRelationalStorageDefinition pDomainStorage)
0733: throws BSException {
0734: try {
0735: ArrayList lStatements = new ArrayList();
0736:
0737: // First we need to get all values and analyse things like column sizes, etc
0738: Properties lEnumerableTypetemplateProperties = DataTypeUtils
0739: .getTypetemplatePropertiesAsProperties(pReferenceDatatype);
0740: boolean lComparable = Boolean.valueOf(
0741: lEnumerableTypetemplateProperties.getProperty(
0742: "Comparable", "false")).booleanValue();
0743:
0744: // Obtain some values from storage definition
0745: RelationalReferenceTable lReferenceTable = pDomainStorage
0746: .getReferenceTable(pReferenceDatatype);
0747:
0748: String lReferenceTableName = lReferenceTable
0749: .getNameOverride();
0750: if (lReferenceTableName == null
0751: || lReferenceTableName.length() == 0)
0752: lReferenceTableName = lReferenceTable
0753: .getNameSuggestion();
0754:
0755: String lReferenceTableValueColumnName = lReferenceTable
0756: .getValueColumnNameOverride();
0757: if (lReferenceTableValueColumnName == null
0758: || lReferenceTableValueColumnName.length() == 0)
0759: lReferenceTableValueColumnName = lReferenceTable
0760: .getValueColumnNameSuggestion();
0761:
0762: String lReferenceTableDescriptionColumnName = lReferenceTable
0763: .getDescriptionColumnNameOverride();
0764: if (lReferenceTableDescriptionColumnName == null
0765: || lReferenceTableDescriptionColumnName.length() == 0)
0766: lReferenceTableDescriptionColumnName = lReferenceTable
0767: .getDescriptionColumnNameSuggestion();
0768:
0769: String lReferenceTableWeightColumnName = null;
0770: String lReferenceTableWeightConstraintName = null;
0771: if (lComparable) {
0772: lReferenceTableWeightColumnName = lReferenceTable
0773: .getWeightColumnNameOverride();
0774: if (lReferenceTableWeightColumnName == null
0775: || lReferenceTableWeightColumnName.length() == 0)
0776: lReferenceTableWeightColumnName = lReferenceTable
0777: .getWeightColumnNameSuggestion();
0778:
0779: lReferenceTableWeightConstraintName = lReferenceTable
0780: .getWeightConstraintNameOverride();
0781: if (lReferenceTableWeightConstraintName == null
0782: || lReferenceTableWeightConstraintName.length() == 0)
0783: lReferenceTableWeightConstraintName = lReferenceTable
0784: .getWeightConstraintNameSuggestion();
0785: }
0786:
0787: String lReferencePrimaryKeyConstraintName = lReferenceTable
0788: .getPrimaryKeyConstraintNameOverride();
0789: if (lReferencePrimaryKeyConstraintName == null
0790: || lReferencePrimaryKeyConstraintName.length() == 0)
0791: lReferencePrimaryKeyConstraintName = lReferenceTable
0792: .getPrimaryKeyConstraintNameSuggestion();
0793:
0794: // First work on the table creation statement
0795: {
0796: // Calculate max length of the description
0797: int lMaxDescriptionSize = 1;
0798: for (int i = 1;; i++) {
0799: String lName = lEnumerableTypetemplateProperties
0800: .getProperty("Value[" + i + "].Name");
0801: if (lName == null || lName.trim().length() == 0)
0802: break; //no more names
0803: String lDescription = lEnumerableTypetemplateProperties
0804: .getProperty(
0805: "Value[" + i + "].Description", "");
0806: if ((lDescription != null)
0807: && (lMaxDescriptionSize < lDescription
0808: .length()))
0809: lMaxDescriptionSize = lDescription.length();
0810: }
0811: Properties lDescriptionJDBCProps = new Properties();
0812: lDescriptionJDBCProps.setProperty("maxsize", Integer
0813: .toString(lMaxDescriptionSize));
0814:
0815: // Build statement on a fly
0816: StringBuffer pStatementBuffer = new StringBuffer();
0817: pStatementBuffer.append("CREATE TABLE ");
0818: pStatementBuffer.append(lReferenceTableName);
0819: pStatementBuffer.append(" (");
0820: // System attributes first
0821: pStatementBuffer.append(mDataBaseMetaData
0822: .suggestColumnDefinition(
0823: lReferenceTableValueColumnName,
0824: pReferenceDatatype, true, false));
0825: pStatementBuffer.append(",");
0826: pStatementBuffer
0827: .append(mDataBaseMetaData
0828: .suggestColumnDefinition(
0829: lReferenceTableDescriptionColumnName,
0830: DataTypeTranslationMetadata.SQL_VARCHAR,
0831: lDescriptionJDBCProps, false,
0832: false));
0833: if (lComparable) {
0834: pStatementBuffer.append(",");
0835: pStatementBuffer
0836: .append(mDataBaseMetaData
0837: .suggestColumnDefinition(
0838: lReferenceTableWeightColumnName,
0839: DataTypeTranslationMetadata.SQL_INTEGER,
0840: new java.util.Properties(),
0841: true, false));
0842: }
0843: pStatementBuffer.append(", CONSTRAINT ");
0844: pStatementBuffer
0845: .append(lReferencePrimaryKeyConstraintName);
0846: pStatementBuffer.append(" PRIMARY KEY (");
0847: pStatementBuffer.append(lReferenceTableValueColumnName);
0848: pStatementBuffer.append(")");
0849: if (lComparable) {
0850: pStatementBuffer.append(",CONSTRAINT ");
0851: pStatementBuffer
0852: .append(lReferenceTableWeightConstraintName);
0853: pStatementBuffer.append(" UNIQUE (");
0854: pStatementBuffer
0855: .append(lReferenceTableWeightColumnName);
0856: pStatementBuffer.append(")");
0857: }
0858: pStatementBuffer.append(");");
0859: lStatements.add(pStatementBuffer.toString());
0860: }
0861:
0862: // Generate table comment if necessary
0863: if (mDataBaseMetaData.needGenerateTableComments()) {
0864: StringBuffer pStatementBuffer = new StringBuffer();
0865: pStatementBuffer.append("COMMENT ON TABLE ");
0866: pStatementBuffer.append(lReferenceTableName);
0867: pStatementBuffer
0868: .append(" IS 'Contains valid values for the ");
0869: pStatementBuffer.append(pReferenceDatatype.getName());
0870: pStatementBuffer
0871: .append(" datatype. Datatype description is ");
0872: String lDescription = pReferenceDatatype
0873: .getDescription();
0874: if (lDescription == null
0875: || lDescription.trim().length() == 0)
0876: lDescription = "missing from the model";
0877: else
0878: lDescription = "\" "
0879: + StringUtils.replace(lDescription, "'",
0880: "''") + " \"";
0881: pStatementBuffer.append(lDescription);
0882: pStatementBuffer.append(".';");
0883: lStatements.add(pStatementBuffer.toString());
0884: }
0885:
0886: // Generate column level coments if necessary
0887: if (mDataBaseMetaData.needGenerateTableColumnComments()) {
0888: {
0889: StringBuffer pStatementBuffer = new StringBuffer();
0890: pStatementBuffer.append("COMMENT ON COLUMN ");
0891: pStatementBuffer.append(lReferenceTableName);
0892: pStatementBuffer.append(".");
0893: pStatementBuffer
0894: .append(lReferenceTableValueColumnName);
0895: pStatementBuffer
0896: .append(" IS 'Valid value for the ");
0897: pStatementBuffer.append(pReferenceDatatype
0898: .getName());
0899: pStatementBuffer.append(" datatype.';");
0900: lStatements.add(pStatementBuffer.toString());
0901: }
0902: {
0903: StringBuffer pStatementBuffer = new StringBuffer();
0904: pStatementBuffer.append("COMMENT ON COLUMN ");
0905: pStatementBuffer.append(lReferenceTableName);
0906: pStatementBuffer.append(".");
0907: pStatementBuffer
0908: .append(lReferenceTableDescriptionColumnName);
0909: pStatementBuffer
0910: .append(" IS 'Description of the valid value.';");
0911: lStatements.add(pStatementBuffer.toString());
0912: }
0913: if (lComparable) {
0914: StringBuffer pStatementBuffer = new StringBuffer();
0915: pStatementBuffer.append("COMMENT ON COLUMN ");
0916: pStatementBuffer.append(lReferenceTableName);
0917: pStatementBuffer.append(".");
0918: pStatementBuffer
0919: .append(lReferenceTableWeightColumnName);
0920: pStatementBuffer
0921: .append(" IS 'Weight to be used in ordering of records.';");
0922: lStatements.add(pStatementBuffer.toString());
0923: }
0924: }
0925:
0926: // Now create the inserts
0927: for (int i = 0;; i++) {
0928: String lName = lEnumerableTypetemplateProperties
0929: .getProperty("Value[" + Integer.toString(i + 1)
0930: + "].Name");
0931: if (lName == null || lName.trim().length() == 0)
0932: break; //no more names
0933: String lDescription = lEnumerableTypetemplateProperties
0934: .getProperty("Value[" + Integer.toString(i + 1)
0935: + "].Description", "");
0936:
0937: // Build statement on a fly
0938: StringBuffer pStatementBuffer = new StringBuffer();
0939: pStatementBuffer.append("INSERT INTO ");
0940: pStatementBuffer.append(lReferenceTableName);
0941: pStatementBuffer.append(" (");
0942: pStatementBuffer.append(lReferenceTableValueColumnName);
0943: pStatementBuffer.append(",");
0944: pStatementBuffer
0945: .append(lReferenceTableDescriptionColumnName);
0946: if (lComparable) {
0947: pStatementBuffer.append(",");
0948: pStatementBuffer
0949: .append(lReferenceTableWeightColumnName);
0950: }
0951: pStatementBuffer.append(") VALUES('");
0952: // Valid value
0953: pStatementBuffer.append(lName);
0954: pStatementBuffer.append("'");
0955: // Description
0956: pStatementBuffer.append(",'");
0957: pStatementBuffer.append(lDescription);
0958: pStatementBuffer.append("'");
0959: if (lComparable) {
0960: // Optional weight
0961: pStatementBuffer.append(",");
0962: pStatementBuffer.append(Integer.toString(i));
0963: }
0964: pStatementBuffer.append(");");
0965: lStatements.add(pStatementBuffer.toString());
0966: }
0967: return (String[]) lStatements
0968: .toArray(new String[lStatements.size()]);
0969: } catch (JmiException e) {
0970: throw new BSServiceProviderException(e);
0971: }
0972: }
0973:
0974: /* Generates state reference data deletion statements */
0975: protected String[] generateStateReferenceTableDeletionStatement(
0976: Domain pDomain, Entity pEntity,
0977: DomainRelationalStorageDefinition pDomainStorage)
0978: throws BSException {
0979: StringBuffer pStatementBuffer = new StringBuffer();
0980: try {
0981: RelationalReferenceTable lReferenceTable = pDomainStorage
0982: .getReferenceTable(pEntity.getStateDataType());
0983: String lReferenceTableName = lReferenceTable
0984: .getNameOverride();
0985: if (lReferenceTableName == null
0986: || lReferenceTableName.length() == 0)
0987: lReferenceTableName = lReferenceTable
0988: .getNameSuggestion();
0989:
0990: // Build statement on a fly
0991: pStatementBuffer.append("DROP TABLE ");
0992: pStatementBuffer.append(lReferenceTableName);
0993: pStatementBuffer.append(";");
0994: return new String[] { pStatementBuffer.toString() };
0995: } catch (JmiException e) {
0996: throw new BSServiceProviderException(e);
0997: }
0998: }
0999:
1000: // Generates state reference data tables from scratch */
1001: protected String[] generateStateReferenceTableCreationStatement(
1002: Domain pDomain, Entity pEntity,
1003: DomainRelationalStorageDefinition pDomainStorage)
1004: throws BSException {
1005: try {
1006: ArrayList lStatements = new ArrayList();
1007:
1008: // Obtain some values from storage definition
1009: RelationalReferenceTable lReferenceTable = pDomainStorage
1010: .getReferenceTable(pEntity.getStateDataType());
1011:
1012: String lReferenceTableName = lReferenceTable
1013: .getNameOverride();
1014: if (lReferenceTableName == null
1015: || lReferenceTableName.length() == 0)
1016: lReferenceTableName = lReferenceTable
1017: .getNameSuggestion();
1018:
1019: String lReferenceTableValueColumnName = lReferenceTable
1020: .getValueColumnNameOverride();
1021: if (lReferenceTableValueColumnName == null
1022: || lReferenceTableValueColumnName.length() == 0)
1023: lReferenceTableValueColumnName = lReferenceTable
1024: .getValueColumnNameSuggestion();
1025:
1026: String lReferenceTableDescriptionColumnName = lReferenceTable
1027: .getDescriptionColumnNameOverride();
1028: if (lReferenceTableDescriptionColumnName == null
1029: || lReferenceTableDescriptionColumnName.length() == 0)
1030: lReferenceTableDescriptionColumnName = lReferenceTable
1031: .getDescriptionColumnNameSuggestion();
1032:
1033: String lReferencePrimaryKeyConstraintName = lReferenceTable
1034: .getPrimaryKeyConstraintNameOverride();
1035: if (lReferencePrimaryKeyConstraintName == null
1036: || lReferencePrimaryKeyConstraintName.length() == 0)
1037: lReferencePrimaryKeyConstraintName = lReferenceTable
1038: .getPrimaryKeyConstraintNameSuggestion();
1039:
1040: // First work on the table creation statement
1041: Collection lStates = pEntity.getStateMachine().getStates();
1042: {
1043: // Calculate max length of the description
1044: int lMaxDescriptionSize = 1;
1045: for (Iterator lStatesIterator = lStates.iterator(); lStatesIterator
1046: .hasNext();) {
1047: State lState = (State) lStatesIterator.next();
1048: String lDescription = lState.getDescription();
1049: if ((lDescription != null)
1050: && (lMaxDescriptionSize < lDescription
1051: .length()))
1052: lMaxDescriptionSize = lDescription.length();
1053: }
1054: Properties lDescriptionJDBCProps = new Properties();
1055: lDescriptionJDBCProps.setProperty("maxsize", Integer
1056: .toString(lMaxDescriptionSize));
1057:
1058: // Build statement on a fly
1059: StringBuffer pStatementBuffer = new StringBuffer();
1060: pStatementBuffer.append("CREATE TABLE ");
1061: pStatementBuffer.append(lReferenceTableName);
1062: pStatementBuffer.append(" (");
1063: // System attributes first
1064: pStatementBuffer.append(mDataBaseMetaData
1065: .suggestColumnDefinition(
1066: lReferenceTableValueColumnName, pEntity
1067: .getStateDataType(), true,
1068: false));
1069: pStatementBuffer.append(",");
1070: pStatementBuffer
1071: .append(mDataBaseMetaData
1072: .suggestColumnDefinition(
1073: lReferenceTableDescriptionColumnName,
1074: DataTypeTranslationMetadata.SQL_VARCHAR,
1075: lDescriptionJDBCProps, false,
1076: false));
1077: pStatementBuffer.append(", CONSTRAINT ");
1078: pStatementBuffer
1079: .append(lReferencePrimaryKeyConstraintName);
1080: pStatementBuffer.append(" PRIMARY KEY (");
1081: pStatementBuffer.append(lReferenceTableValueColumnName);
1082: pStatementBuffer.append("));");
1083: lStatements.add(pStatementBuffer.toString());
1084: }
1085:
1086: // Generate table comment if necessary
1087: if (mDataBaseMetaData.needGenerateTableComments()) {
1088: StringBuffer pStatementBuffer = new StringBuffer();
1089: pStatementBuffer.append("COMMENT ON TABLE ");
1090: pStatementBuffer.append(lReferenceTableName);
1091: pStatementBuffer
1092: .append(" IS 'Stores valid values for the ");
1093: pStatementBuffer.append(pEntity.getName());
1094: pStatementBuffer.append(" entity state.';");
1095: lStatements.add(pStatementBuffer.toString());
1096: }
1097:
1098: // Generate column level coments if necessary
1099: if (mDataBaseMetaData.needGenerateTableColumnComments()) {
1100: {
1101: StringBuffer pStatementBuffer = new StringBuffer();
1102: pStatementBuffer.append("COMMENT ON COLUMN ");
1103: pStatementBuffer.append(lReferenceTableName);
1104: pStatementBuffer.append(".");
1105: pStatementBuffer
1106: .append(lReferenceTableValueColumnName);
1107: pStatementBuffer
1108: .append(" IS 'Valid value for the ");
1109: pStatementBuffer.append(pEntity.getName());
1110: pStatementBuffer.append(" entity state.';");
1111: lStatements.add(pStatementBuffer.toString());
1112: }
1113: {
1114: StringBuffer pStatementBuffer = new StringBuffer();
1115: pStatementBuffer.append("COMMENT ON COLUMN ");
1116: pStatementBuffer.append(lReferenceTableName);
1117: pStatementBuffer.append(".");
1118: pStatementBuffer
1119: .append(lReferenceTableDescriptionColumnName);
1120: pStatementBuffer
1121: .append(" IS 'Description of the entity state.';");
1122: lStatements.add(pStatementBuffer.toString());
1123: }
1124: }
1125: // Now create the inserts
1126: for (Iterator lStatesIterator = lStates.iterator(); lStatesIterator
1127: .hasNext();) {
1128: State lState = (State) lStatesIterator.next();
1129: String lDescription = lState.getDescription();
1130: if (lDescription == null)
1131: lDescription = "";
1132:
1133: // Build statement on a fly
1134: StringBuffer pStatementBuffer = new StringBuffer();
1135: pStatementBuffer.append("INSERT INTO ");
1136: pStatementBuffer.append(lReferenceTableName);
1137: pStatementBuffer.append(" (");
1138: pStatementBuffer.append(lReferenceTableValueColumnName);
1139: pStatementBuffer.append(",");
1140: pStatementBuffer
1141: .append(lReferenceTableDescriptionColumnName);
1142: pStatementBuffer.append(") VALUES('");
1143: // Valid value
1144: pStatementBuffer.append(lState.getName());
1145: pStatementBuffer.append("'");
1146: // Description
1147: pStatementBuffer.append(",'");
1148: pStatementBuffer.append(lDescription);
1149: pStatementBuffer.append("'");
1150: pStatementBuffer.append(");");
1151: lStatements.add(pStatementBuffer.toString());
1152: }
1153: return (String[]) lStatements
1154: .toArray(new String[lStatements.size()]);
1155: } catch (JmiException e) {
1156: throw new BSServiceProviderException(e);
1157: }
1158: }
1159:
1160: /* Generates database domain tables from scratch */
1161: protected String[] generateEntityConstraintsDeletionStatement(
1162: Entity pEntity,
1163: DomainRelationalStorageDefinition pDomainStorage)
1164: throws BSException {
1165: try {
1166: // Setup typetemplates necessary for the datatypes
1167: Domain lDomain = pDomainStorage.getDomain();
1168: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
1169: .getSystem();
1170: Enterprise lEnterprise = lSystem.getEnterprise();
1171: TypeTemplate lEnumerableValueTypeTemplate = lEnterprise
1172: .getDesignLibrary().getDataDictionary("core")
1173: .getTypeTemplate("EnumerableValueField");
1174:
1175: ArrayList lReturnStatements = new ArrayList();
1176: RelationalEntityTable lEntityTable = pDomainStorage
1177: .getEntityTable(pEntity);
1178: String lEntityTableName = lEntityTable.getNameOverride();
1179: if (lEntityTableName == null
1180: || lEntityTableName.length() == 0)
1181: lEntityTableName = lEntityTable.getNameSuggestion();
1182:
1183: // Work on the foreign key constraint dealing with inheritance if necessary
1184: if (pEntity.getSupertype() != null) {
1185: String lSupertypeConstraintName = lEntityTable
1186: .getSupertypeConstraintNameOverride();
1187: if (lSupertypeConstraintName == null
1188: || lSupertypeConstraintName.length() == 0)
1189: lSupertypeConstraintName = lEntityTable
1190: .getSupertypeConstraintNameSuggestion();
1191:
1192: StringBuffer pStatementBuffer = new StringBuffer();
1193: pStatementBuffer.append("ALTER TABLE ");
1194: pStatementBuffer.append(lEntityTableName);
1195: pStatementBuffer.append(" DROP CONSTRAINT ");
1196: pStatementBuffer.append(lSupertypeConstraintName);
1197: pStatementBuffer.append(";");
1198: lReturnStatements.add(pStatementBuffer.toString());
1199: }
1200:
1201: Collection lRelationalEntityTableAssociationRoleList = lEntityTable
1202: .getReferenceColumns();
1203:
1204: Collection lReferences = pEntity.getReferences();
1205: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
1206: .hasNext();) {
1207: AssociationRole lRole = (AssociationRole) lReferencesIterator
1208: .next();
1209: // Association constraint is only necessary if this entity has a reference
1210: if (CommonUtil.doesEntityStoreReference(lRole)) {
1211: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
1212: .getReferenceColumn(lRole);
1213:
1214: String lConstraintName = lRelationalEntityTableAssociationRole
1215: .getReferentialConstraintNameOverride();
1216: if (lConstraintName == null
1217: || lConstraintName.length() == 0)
1218: lConstraintName = lRelationalEntityTableAssociationRole
1219: .getReferentialConstraintNameSuggestion();
1220: StringBuffer pStatementBuffer = new StringBuffer();
1221: pStatementBuffer.append("ALTER TABLE ");
1222: pStatementBuffer.append(lEntityTableName);
1223: pStatementBuffer.append(" DROP CONSTRAINT ");
1224: pStatementBuffer.append(lConstraintName);
1225: pStatementBuffer.append(";");
1226: lReturnStatements.add(pStatementBuffer.toString());
1227: }
1228: }
1229: // Work on possible constraint resulting from entity having a state
1230: if (pEntity.getStateMachine() != null) {
1231: String lStateForeignKeyConstraintName = lEntityTable
1232: .getStateReferentialConstraintNameOverride();
1233: if (lStateForeignKeyConstraintName == null
1234: || lStateForeignKeyConstraintName.length() == 0)
1235: lStateForeignKeyConstraintName = lEntityTable
1236: .getStateReferentialConstraintNameSuggestion();
1237:
1238: StringBuffer pStatementBuffer = new StringBuffer();
1239: pStatementBuffer.append("ALTER TABLE ");
1240: pStatementBuffer.append(lEntityTableName);
1241: pStatementBuffer.append(" DROP CONSTRAINT ");
1242: pStatementBuffer.append(lStateForeignKeyConstraintName);
1243: pStatementBuffer.append(";");
1244: lReturnStatements.add(pStatementBuffer.toString());
1245: }
1246: Collection lAttributes = pEntity.getAttributes();
1247: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
1248: .hasNext();) {
1249: Attribute lAttribute = (Attribute) lAttributesIterator
1250: .next();
1251: DataType lAttributeDatatype = lAttribute.getDataType();
1252: TypeTemplate lTypetemplate = lAttributeDatatype
1253: .getTypetemplate();
1254: if (lTypetemplate != null
1255: && lTypetemplate
1256: .equals(lEnumerableValueTypeTemplate)) {
1257: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
1258: .getAttributeColumn(lAttribute);
1259:
1260: String lForeignKeyConstraintName = lRelationalEntityTableAttribute
1261: .getReferentialConstraintNameOverride();
1262: if (lForeignKeyConstraintName == null
1263: || lForeignKeyConstraintName.length() == 0)
1264: lForeignKeyConstraintName = lRelationalEntityTableAttribute
1265: .getReferentialConstraintNameSuggestion();
1266:
1267: StringBuffer pStatementBuffer = new StringBuffer();
1268: pStatementBuffer.append("ALTER TABLE ");
1269: pStatementBuffer.append(lEntityTableName);
1270: pStatementBuffer.append(" DROP CONSTRAINT ");
1271: pStatementBuffer.append(lForeignKeyConstraintName);
1272: pStatementBuffer.append(";");
1273: lReturnStatements.add(pStatementBuffer.toString());
1274: }
1275: }
1276: return (String[]) lReturnStatements
1277: .toArray(new String[lReturnStatements.size()]);
1278: } catch (JmiException e) {
1279: throw new BSServiceProviderException(e);
1280: }
1281: }
1282:
1283: /* Generates constraints deletion ststement for the plural association tables */
1284: protected String[] generateAssociationConstraintsDeletionStatement(
1285: Association pAssociation,
1286: DomainRelationalStorageDefinition pDomainStorage)
1287: throws BSException {
1288: try {
1289: // Association table only exists for the associations where both sides refuse to have a reference
1290: if (CommonUtil.doEntitiesStoreReference(pAssociation))
1291: return null; // No separate table
1292: AssociationRole[] lRoles = (AssociationRole[]) pAssociation
1293: .getRoles().toArray(new AssociationRole[2]);
1294: AssociationRole lRoleA = lRoles[0];
1295: AssociationRole lRoleB = lRoles[1];
1296: ArrayList lReturnStatements = new ArrayList();
1297: RelationalAssociationTable lAssociationTable = pDomainStorage
1298: .getAssociationTable(pAssociation);
1299: String lTableName = lAssociationTable.getNameOverride();
1300: if (lTableName == null || lTableName.length() == 0)
1301: lTableName = lAssociationTable.getNameSuggestion();
1302:
1303: // Deal with role A
1304: {
1305: String lConstraintName = lAssociationTable
1306: .getFirstRoleReferentialConstraintNameOverride();
1307: if (lConstraintName == null
1308: || lConstraintName.length() == 0)
1309: lConstraintName = lAssociationTable
1310: .getFirstRoleReferentialConstraintNameSuggestion();
1311:
1312: StringBuffer pStatementBuffer = new StringBuffer();
1313: pStatementBuffer.append("ALTER TABLE ");
1314: pStatementBuffer.append(lTableName);
1315: pStatementBuffer.append(" DROP CONSTRAINT ");
1316: pStatementBuffer.append(lConstraintName);
1317: pStatementBuffer.append(";");
1318: lReturnStatements.add(pStatementBuffer.toString());
1319: }
1320:
1321: // Deal with role B
1322: {
1323: String lConstraintName = lAssociationTable
1324: .getSecondRoleReferentialConstraintNameOverride();
1325: if (lConstraintName == null
1326: || lConstraintName.length() == 0)
1327: lConstraintName = lAssociationTable
1328: .getSecondRoleReferentialConstraintNameSuggestion();
1329:
1330: StringBuffer pStatementBuffer = new StringBuffer();
1331: pStatementBuffer.append("ALTER TABLE ");
1332: pStatementBuffer.append(lTableName);
1333: pStatementBuffer.append(" DROP CONSTRAINT ");
1334: pStatementBuffer.append(lConstraintName);
1335: pStatementBuffer.append(";");
1336: lReturnStatements.add(pStatementBuffer.toString());
1337: }
1338: return (String[]) lReturnStatements
1339: .toArray(new String[lReturnStatements.size()]);
1340: } catch (JmiException e) {
1341: throw new BSServiceProviderException(e);
1342: }
1343: }
1344:
1345: /* Generates database domain tables from scratch */
1346: protected String[] generateEntityConstraintsCreationStatement(
1347: Entity pEntity,
1348: DomainRelationalStorageDefinition pDomainStorage)
1349: throws BSException {
1350: try {
1351: // Setup typetemplates necessary for the datatypes
1352: Domain lDomain = pDomainStorage.getDomain();
1353: com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.System lSystem = lDomain
1354: .getSystem();
1355: Enterprise lEnterprise = lSystem.getEnterprise();
1356: TypeTemplate lEnumerableValueTypeTemplate = lEnterprise
1357: .getDesignLibrary().getDataDictionary("core")
1358: .getTypeTemplate("EnumerableValueField");
1359:
1360: ArrayList lReturnStatements = new ArrayList();
1361:
1362: RelationalEntityTable lEntityTable = pDomainStorage
1363: .getEntityTable(pEntity);
1364: String lEntityTableName = lEntityTable.getNameOverride();
1365: if (lEntityTableName == null
1366: || lEntityTableName.length() == 0)
1367: lEntityTableName = lEntityTable.getNameSuggestion();
1368: String lInstanceIdColumnName = lEntityTable
1369: .getInstanceIdColumnNameOverride();
1370: if (lInstanceIdColumnName == null
1371: || lInstanceIdColumnName.length() == 0)
1372: lInstanceIdColumnName = lEntityTable
1373: .getInstanceIdColumnNameSuggestion();
1374:
1375: // Work on the foreign key constraint dealing with inheritance if necessary
1376: Entity lSupertypeEntity = pEntity.getSupertype();
1377: if (lSupertypeEntity != null) {
1378: RelationalEntityTable lSupertypeEntityTable = pDomainStorage
1379: .getEntityTable(lSupertypeEntity);
1380: String lSupertypeEntityTableName = lSupertypeEntityTable
1381: .getNameOverride();
1382: if (lSupertypeEntityTableName == null
1383: || lSupertypeEntityTableName.length() == 0)
1384: lSupertypeEntityTableName = lSupertypeEntityTable
1385: .getNameSuggestion();
1386:
1387: String lSupertypeEntityTableInstanceIdColumnName = lSupertypeEntityTable
1388: .getInstanceIdColumnNameOverride();
1389: if (lSupertypeEntityTableInstanceIdColumnName == null
1390: || lSupertypeEntityTableInstanceIdColumnName
1391: .length() == 0)
1392: lSupertypeEntityTableInstanceIdColumnName = lSupertypeEntityTable
1393: .getInstanceIdColumnNameSuggestion();
1394:
1395: String lSupertypeConstraintName = lEntityTable
1396: .getSupertypeConstraintNameOverride();
1397: if (lSupertypeConstraintName == null
1398: || lSupertypeConstraintName.length() == 0)
1399: lSupertypeConstraintName = lEntityTable
1400: .getSupertypeConstraintNameSuggestion();
1401:
1402: StringBuffer pStatementBuffer = new StringBuffer();
1403: pStatementBuffer.append("ALTER TABLE ");
1404: pStatementBuffer.append(lEntityTableName);
1405: pStatementBuffer.append(" ADD CONSTRAINT ");
1406: pStatementBuffer.append(lSupertypeConstraintName);
1407: pStatementBuffer.append(" FOREIGN KEY (");
1408: pStatementBuffer.append(lInstanceIdColumnName);
1409: pStatementBuffer.append(") REFERENCES ");
1410: pStatementBuffer.append(lSupertypeEntityTableName);
1411: pStatementBuffer.append("(");
1412: pStatementBuffer
1413: .append(lSupertypeEntityTableInstanceIdColumnName);
1414: pStatementBuffer.append(") ON DELETE CASCADE;");
1415: lReturnStatements.add(pStatementBuffer.toString());
1416: }
1417:
1418: // Work on possible constraints resulting from associations
1419: Collection lReferences = pEntity.getReferences();
1420: AssociationRole lOwnerReference = pEntity
1421: .getOwnerReference();
1422: for (Iterator lReferencesIterator = lReferences.iterator(); lReferencesIterator
1423: .hasNext();) {
1424: AssociationRole lReference = (AssociationRole) lReferencesIterator
1425: .next();
1426: // Association constraint is only necessary if this entity has a reference
1427: if (CommonUtil.doesEntityStoreReference(lReference)) {
1428: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
1429: .getReferenceColumn(lReference);
1430: String lAssociationConstraintName = lRelationalEntityTableAssociationRole
1431: .getReferentialConstraintNameOverride();
1432: if (lAssociationConstraintName == null
1433: || lAssociationConstraintName.length() == 0)
1434: lAssociationConstraintName = lRelationalEntityTableAssociationRole
1435: .getReferentialConstraintNameSuggestion();
1436: String lAssociationColumnName = lRelationalEntityTableAssociationRole
1437: .getColumnNameOverride();
1438: if (lAssociationColumnName == null
1439: || lAssociationColumnName.length() == 0)
1440: lAssociationColumnName = lRelationalEntityTableAssociationRole
1441: .getColumnNameSuggestion();
1442:
1443: RelationalEntityTable lReferencedEntityTable = pDomainStorage
1444: .getEntityTable(lReference.getEntity());
1445: String lReferencedEntityTableName = lReferencedEntityTable
1446: .getNameOverride();
1447: if (lReferencedEntityTableName == null
1448: || lReferencedEntityTableName.length() == 0)
1449: lReferencedEntityTableName = lReferencedEntityTable
1450: .getNameSuggestion();
1451: String lReferencedEntityTableInstanceIdColumnName = lReferencedEntityTable
1452: .getInstanceIdColumnNameOverride();
1453: if (lReferencedEntityTableInstanceIdColumnName == null
1454: || lReferencedEntityTableInstanceIdColumnName
1455: .length() == 0)
1456: lReferencedEntityTableInstanceIdColumnName = lReferencedEntityTable
1457: .getInstanceIdColumnNameSuggestion();
1458:
1459: // Number of special cases :
1460: // 1 - if we are referencing an owner (since owner relationship is always singular
1461: // child always has a foreighn key to the parent) than we have to put on delete cascade
1462: // which will provide for automatic delete of the child record
1463: StringBuffer pStatementBuffer = new StringBuffer();
1464: pStatementBuffer.append("ALTER TABLE ");
1465: pStatementBuffer.append(lEntityTableName);
1466: pStatementBuffer.append(" ADD CONSTRAINT ");
1467: pStatementBuffer.append(lAssociationConstraintName);
1468: pStatementBuffer.append(" FOREIGN KEY (");
1469: pStatementBuffer.append(lAssociationColumnName);
1470: pStatementBuffer.append(") REFERENCES ");
1471: pStatementBuffer.append(lReferencedEntityTableName);
1472: pStatementBuffer.append("(");
1473: pStatementBuffer
1474: .append(lReferencedEntityTableInstanceIdColumnName);
1475: pStatementBuffer.append(")");
1476: // Insert ownership constraint if necessary
1477: //TODO: For now will only insert mandatory (not null) constraint for owner entity. For the mandatory associations we will have to come back and think how to do it
1478: if (lReference.equals(lOwnerReference)) {
1479: pStatementBuffer.append(" ON DELETE CASCADE");
1480: } else {
1481: pStatementBuffer.append(" ON DELETE SET NULL");
1482: }
1483: pStatementBuffer.append(";");
1484: lReturnStatements.add(pStatementBuffer.toString());
1485: }
1486: }
1487: // Work on possible constraint resulting from entity having a state
1488: if (pEntity.getStateMachine() != null) {
1489: RelationalReferenceTable lReferenceTable = pDomainStorage
1490: .getReferenceTable(pEntity.getStateDataType());
1491: String lReferenceTableName = lReferenceTable
1492: .getNameOverride();
1493: if (lReferenceTableName == null
1494: || lReferenceTableName.length() == 0)
1495: lReferenceTableName = lReferenceTable
1496: .getNameSuggestion();
1497:
1498: String lReferenceTableValueColumnName = lReferenceTable
1499: .getValueColumnNameOverride();
1500: if (lReferenceTableValueColumnName == null
1501: || lReferenceTableValueColumnName.length() == 0)
1502: lReferenceTableValueColumnName = lReferenceTable
1503: .getValueColumnNameSuggestion();
1504:
1505: String lEntityTableStateColumnName = lEntityTable
1506: .getStateColumnNameOverride();
1507: if (lEntityTableStateColumnName == null
1508: || lEntityTableStateColumnName.length() == 0)
1509: lEntityTableStateColumnName = lEntityTable
1510: .getStateColumnNameSuggestion();
1511:
1512: String lStateForeignKeyConstraintName = lEntityTable
1513: .getStateReferentialConstraintNameOverride();
1514: if (lStateForeignKeyConstraintName == null
1515: || lStateForeignKeyConstraintName.length() == 0)
1516: lStateForeignKeyConstraintName = lEntityTable
1517: .getStateReferentialConstraintNameSuggestion();
1518:
1519: StringBuffer pStatementBuffer = new StringBuffer();
1520: pStatementBuffer.append("ALTER TABLE ");
1521: pStatementBuffer.append(lEntityTableName);
1522: pStatementBuffer.append(" ADD CONSTRAINT ");
1523: pStatementBuffer.append(lStateForeignKeyConstraintName);
1524: pStatementBuffer.append(" FOREIGN KEY ( ");
1525: pStatementBuffer.append(lEntityTableStateColumnName);
1526: pStatementBuffer.append(" ) REFERENCES ");
1527: pStatementBuffer.append(lReferenceTableName);
1528: pStatementBuffer.append("(");
1529: pStatementBuffer.append(lReferenceTableValueColumnName);
1530: pStatementBuffer.append(");");
1531: lReturnStatements.add(pStatementBuffer.toString());
1532: }
1533:
1534: // Work on possible constraints resulting from enumerable types attributes
1535: Collection lAttributes = pEntity.getAttributes();
1536: for (Iterator lAttributesIterator = lAttributes.iterator(); lAttributesIterator
1537: .hasNext();) {
1538: Attribute lAttribute = (Attribute) lAttributesIterator
1539: .next();
1540: DataType lAttributeDatatype = lAttribute.getDataType();
1541: TypeTemplate lTypetemplate = lAttributeDatatype
1542: .getTypetemplate();
1543: if (lTypetemplate != null
1544: && lTypetemplate
1545: .equals(lEnumerableValueTypeTemplate)) {
1546: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
1547: .getAttributeColumn(lAttribute);
1548: String lAttributeColumnName = lRelationalEntityTableAttribute
1549: .getColumnNameOverride();
1550: if (lAttributeColumnName == null
1551: || lAttributeColumnName.length() == 0)
1552: lAttributeColumnName = lRelationalEntityTableAttribute
1553: .getColumnNameSuggestion();
1554:
1555: RelationalReferenceTable lReferenceTable = pDomainStorage
1556: .getReferenceTable(lAttributeDatatype);
1557: String lReferenceTableName = lReferenceTable
1558: .getNameOverride();
1559: if (lReferenceTableName == null
1560: || lReferenceTableName.length() == 0)
1561: lReferenceTableName = lReferenceTable
1562: .getNameSuggestion();
1563:
1564: String lReferencedColumnName = lReferenceTable
1565: .getValueColumnNameOverride();
1566: if (lReferencedColumnName == null
1567: || lReferencedColumnName.length() == 0)
1568: lReferencedColumnName = lReferenceTable
1569: .getValueColumnNameSuggestion();
1570:
1571: String lForeignKeyConstraintName = lRelationalEntityTableAttribute
1572: .getReferentialConstraintNameOverride();
1573: if (lForeignKeyConstraintName == null
1574: || lForeignKeyConstraintName.length() == 0)
1575: lForeignKeyConstraintName = lRelationalEntityTableAttribute
1576: .getReferentialConstraintNameSuggestion();
1577:
1578: StringBuffer pStatementBuffer = new StringBuffer();
1579: pStatementBuffer.append("ALTER TABLE ");
1580: pStatementBuffer.append(lEntityTableName);
1581: pStatementBuffer.append(" ADD CONSTRAINT ");
1582: pStatementBuffer.append(lForeignKeyConstraintName);
1583: pStatementBuffer.append(" FOREIGN KEY (");
1584: pStatementBuffer.append(lAttributeColumnName);
1585: pStatementBuffer.append(") REFERENCES ");
1586: pStatementBuffer.append(lReferenceTableName);
1587: pStatementBuffer.append("(");
1588: pStatementBuffer.append(lReferencedColumnName);
1589: pStatementBuffer.append(");");
1590: lReturnStatements.add(pStatementBuffer.toString());
1591: }
1592: }
1593: return (String[]) lReturnStatements
1594: .toArray(new String[lReturnStatements.size()]);
1595: } catch (JmiException e) {
1596: throw new BSServiceProviderException(e);
1597: }
1598: }
1599:
1600: /* Generates constraints resulting from associations */
1601: protected String[] generateAssociationConstraintsCreationStatement(
1602: Association pAssociation,
1603: DomainRelationalStorageDefinition pDomainStorage)
1604: throws BSException {
1605: try {
1606: // Association table only exists for the associations where both sides refuse to have a reference
1607: if (CommonUtil.doEntitiesStoreReference(pAssociation))
1608: return null; // No separate table
1609: AssociationRole[] lRoles = (AssociationRole[]) pAssociation
1610: .getRoles().toArray(new AssociationRole[2]);
1611: AssociationRole lRoleA = lRoles[0];
1612: AssociationRole lRoleB = lRoles[1];
1613: ArrayList lReturnStatements = new ArrayList();
1614: RelationalAssociationTable lAssociationTable = pDomainStorage
1615: .getAssociationTable(pAssociation);
1616: String lTableName = lAssociationTable.getNameOverride();
1617: if (lTableName == null || lTableName.length() == 0)
1618: lTableName = lAssociationTable.getNameSuggestion();
1619: // Deal with role A
1620: {
1621: String lRoleAConstraintName = lAssociationTable
1622: .getFirstRoleReferentialConstraintNameOverride();
1623: if (lRoleAConstraintName == null
1624: || lRoleAConstraintName.length() == 0)
1625: lRoleAConstraintName = lAssociationTable
1626: .getFirstRoleReferentialConstraintNameSuggestion();
1627:
1628: String lRoleAColumnName = lAssociationTable
1629: .getFirstRoleColumnNameOverride();
1630: if (lRoleAColumnName == null
1631: || lRoleAColumnName.length() == 0)
1632: lRoleAColumnName = lAssociationTable
1633: .getFirstRoleColumnNameSuggestion();
1634:
1635: RelationalEntityTable lReferencedEntityTable = pDomainStorage
1636: .getEntityTable(lRoleA.getEntity());
1637: String lReferencedEntityTableName = lReferencedEntityTable
1638: .getNameOverride();
1639: if (lReferencedEntityTableName == null
1640: || lReferencedEntityTableName.length() == 0)
1641: lReferencedEntityTableName = lReferencedEntityTable
1642: .getNameSuggestion();
1643: String lReferencedEntityInstanceIdColumnName = lReferencedEntityTable
1644: .getInstanceIdColumnNameOverride();
1645: if (lReferencedEntityInstanceIdColumnName == null
1646: || lReferencedEntityInstanceIdColumnName
1647: .length() == 0)
1648: lReferencedEntityInstanceIdColumnName = lReferencedEntityTable
1649: .getInstanceIdColumnNameSuggestion();
1650:
1651: StringBuffer pStatementBuffer = new StringBuffer();
1652: pStatementBuffer.append("ALTER TABLE ");
1653: pStatementBuffer.append(lTableName);
1654: pStatementBuffer.append(" ADD CONSTRAINT ");
1655: pStatementBuffer.append(lRoleAConstraintName);
1656: pStatementBuffer.append(" FOREIGN KEY (");
1657: pStatementBuffer.append(lRoleAColumnName);
1658: pStatementBuffer.append(") REFERENCES ");
1659: pStatementBuffer.append(lReferencedEntityTableName);
1660: pStatementBuffer.append("(");
1661: pStatementBuffer
1662: .append(lReferencedEntityInstanceIdColumnName);
1663: pStatementBuffer.append(") ON DELETE CASCADE;");
1664: lReturnStatements.add(pStatementBuffer.toString());
1665: }
1666:
1667: // Deal with role B
1668: {
1669:
1670: String lRoleBConstraintName = lAssociationTable
1671: .getSecondRoleReferentialConstraintNameOverride();
1672: if (lRoleBConstraintName == null
1673: || lRoleBConstraintName.length() == 0)
1674: lRoleBConstraintName = lAssociationTable
1675: .getSecondRoleReferentialConstraintNameSuggestion();
1676:
1677: String lRoleBColumnName = lAssociationTable
1678: .getSecondRoleColumnNameOverride();
1679: if (lRoleBColumnName == null
1680: || lRoleBColumnName.length() == 0)
1681: lRoleBColumnName = lAssociationTable
1682: .getSecondRoleColumnNameSuggestion();
1683:
1684: RelationalEntityTable lReferencedEntityTable = pDomainStorage
1685: .getEntityTable(lRoleB.getEntity());
1686: String lReferencedEntityTableName = lReferencedEntityTable
1687: .getNameOverride();
1688: if (lReferencedEntityTableName == null
1689: || lReferencedEntityTableName.length() == 0)
1690: lReferencedEntityTableName = lReferencedEntityTable
1691: .getNameSuggestion();
1692: String lReferencedEntityInstanceIdColumnName = lReferencedEntityTable
1693: .getInstanceIdColumnNameOverride();
1694: if (lReferencedEntityInstanceIdColumnName == null
1695: || lReferencedEntityInstanceIdColumnName
1696: .length() == 0)
1697: lReferencedEntityInstanceIdColumnName = lReferencedEntityTable
1698: .getInstanceIdColumnNameSuggestion();
1699:
1700: StringBuffer pStatementBuffer = new StringBuffer();
1701: pStatementBuffer.append("ALTER TABLE ");
1702: pStatementBuffer.append(lTableName);
1703: pStatementBuffer.append(" ADD CONSTRAINT ");
1704: pStatementBuffer.append(lRoleBConstraintName);
1705: pStatementBuffer.append(" FOREIGN KEY (");
1706: pStatementBuffer.append(lRoleBColumnName);
1707: pStatementBuffer.append(") REFERENCES ");
1708: pStatementBuffer.append(lReferencedEntityTableName);
1709: pStatementBuffer.append("(");
1710: pStatementBuffer
1711: .append(lReferencedEntityInstanceIdColumnName);
1712: pStatementBuffer.append(") ON DELETE CASCADE;");
1713: lReturnStatements.add(pStatementBuffer.toString());
1714: }
1715: return (String[]) lReturnStatements
1716: .toArray(new String[lReturnStatements.size()]);
1717: } catch (JmiException e) {
1718: throw new BSServiceProviderException(e);
1719: }
1720: }
1721:
1722: /* Generates deletion of the association tables */
1723: protected String[] generateAssociationTableDeletionStatement(
1724: Association pAssociation,
1725: DomainRelationalStorageDefinition pDomainStorage)
1726: throws BSException {
1727: try {
1728: // Association table only exists for the associations where both sides refuse to have a reference
1729: if (CommonUtil.doEntitiesStoreReference(pAssociation))
1730: return null; // No separate table
1731: AssociationRole[] lRoles = (AssociationRole[]) pAssociation
1732: .getRoles().toArray(new AssociationRole[2]);
1733: AssociationRole lRoleA = lRoles[0];
1734: AssociationRole lRoleB = lRoles[1];
1735: RelationalAssociationTable lAssociationTable = pDomainStorage
1736: .getAssociationTable(pAssociation);
1737: String lTableName = lAssociationTable.getNameOverride();
1738: if (lTableName == null || lTableName.length() == 0)
1739: lTableName = lAssociationTable.getNameSuggestion();
1740: // Build statement on a fly
1741: StringBuffer pStatementBuffer = new StringBuffer();
1742: pStatementBuffer.append("DROP TABLE ");
1743: pStatementBuffer.append(lTableName);
1744: pStatementBuffer.append(";");
1745: return new String[] { pStatementBuffer.toString() };
1746: } catch (JmiException e) {
1747: throw new BSServiceProviderException(e);
1748: }
1749: }
1750:
1751: /* Generates database domain tables from scratch */
1752: protected String[] generateAssociationTableCreationStatement(
1753: Association pAssociation,
1754: DomainRelationalStorageDefinition pDomainStorage)
1755: throws BSException {
1756: try {
1757: // Association table only exists for the associations where both sides refuse to have a reference
1758: if (CommonUtil.doEntitiesStoreReference(pAssociation))
1759: return null; // No separate table
1760: AssociationRole[] lRoles = (AssociationRole[]) pAssociation
1761: .getRoles().toArray(new AssociationRole[2]);
1762: AssociationRole lRoleA = lRoles[0];
1763: AssociationRole lRoleB = lRoles[1];
1764: RelationalAssociationTable lAssociationTable = pDomainStorage
1765: .getAssociationTable(pAssociation);
1766:
1767: String lTableName = lAssociationTable.getNameOverride();
1768: if (lTableName == null || lTableName.length() == 0)
1769: lTableName = lAssociationTable.getNameSuggestion();
1770:
1771: String lPrimaryKeyName = lAssociationTable
1772: .getPrimaryKeyConstraintNameOverride();
1773: if (lPrimaryKeyName == null
1774: || lPrimaryKeyName.length() == 0)
1775: lPrimaryKeyName = lAssociationTable
1776: .getPrimaryKeyConstraintNameSuggestion();
1777:
1778: String lRoleAColumnName = lAssociationTable
1779: .getFirstRoleColumnNameOverride();
1780: if (lRoleAColumnName == null
1781: || lRoleAColumnName.length() == 0)
1782: lRoleAColumnName = lAssociationTable
1783: .getFirstRoleColumnNameSuggestion();
1784:
1785: String lRoleBColumnName = lAssociationTable
1786: .getSecondRoleColumnNameOverride();
1787: if (lRoleBColumnName == null
1788: || lRoleBColumnName.length() == 0)
1789: lRoleBColumnName = lAssociationTable
1790: .getSecondRoleColumnNameSuggestion();
1791:
1792: ArrayList lStatements = new ArrayList();
1793: // Generate table creation statement
1794: {
1795: // Build statement on a fly
1796: StringBuffer pStatementBuffer = new StringBuffer();
1797: pStatementBuffer.append("CREATE TABLE ");
1798: pStatementBuffer.append(lTableName);
1799: pStatementBuffer.append(" (");
1800: // Role A column
1801: pStatementBuffer.append(mDataBaseMetaData
1802: .suggestColumnDefinition(lRoleAColumnName,
1803: lRoleA.getEntity()
1804: .getInstanceIdDataType(), true,
1805: true));
1806: // Role B column
1807: pStatementBuffer.append(",");
1808: pStatementBuffer.append(mDataBaseMetaData
1809: .suggestColumnDefinition(lRoleBColumnName,
1810: lRoleB.getEntity()
1811: .getInstanceIdDataType(), true,
1812: true));
1813: // Now to the primary key
1814: pStatementBuffer.append(", CONSTRAINT ");
1815: pStatementBuffer.append(lPrimaryKeyName);
1816: pStatementBuffer.append(" PRIMARY KEY (");
1817: pStatementBuffer.append(lRoleAColumnName);
1818: pStatementBuffer.append(", ");
1819: pStatementBuffer.append(lRoleBColumnName);
1820: pStatementBuffer.append("));");
1821: lStatements.add(pStatementBuffer.toString());
1822: }
1823:
1824: // Generate table comment if necessary
1825: if (mDataBaseMetaData.needGenerateTableComments()) {
1826: StringBuffer pStatementBuffer = new StringBuffer();
1827: pStatementBuffer.append("COMMENT ON TABLE ");
1828: pStatementBuffer.append(lTableName);
1829: pStatementBuffer.append(" IS 'Association ");
1830: pStatementBuffer.append(pAssociation.getName());
1831: pStatementBuffer.append(" : ");
1832: String lDescription = pAssociation.getDescription();
1833: if (lDescription == null
1834: || lDescription.trim().length() == 0)
1835: lDescription = "Description is missing from the model";
1836: else
1837: lDescription = "\" "
1838: + StringUtils.replace(lDescription, "'",
1839: "''") + " \"";
1840: pStatementBuffer.append(lDescription);
1841: pStatementBuffer.append(".';");
1842: lStatements.add(pStatementBuffer.toString());
1843: }
1844:
1845: // Generate table column comments if necessary
1846: if (mDataBaseMetaData.needGenerateTableColumnComments()) {
1847: // Generate role a comment
1848: {
1849: StringBuffer pStatementBuffer = new StringBuffer();
1850: pStatementBuffer.append("COMMENT ON COLUMN ");
1851: pStatementBuffer.append(lTableName);
1852: pStatementBuffer.append(".");
1853: pStatementBuffer.append(lRoleAColumnName);
1854: pStatementBuffer.append(" IS 'Association role ");
1855: pStatementBuffer.append(lRoleA.getName());
1856: pStatementBuffer.append(" : ");
1857: String lDescription = lRoleA.getDescription();
1858: if (lDescription == null
1859: || lDescription.trim().length() == 0)
1860: lDescription = "Description is missing from the model";
1861: else
1862: lDescription = "\" "
1863: + StringUtils.replace(lDescription,
1864: "'", "''") + " \"";
1865: pStatementBuffer.append(lDescription);
1866: pStatementBuffer.append(".';");
1867: lStatements.add(pStatementBuffer.toString());
1868: }
1869: // Generate role b comment
1870: {
1871: StringBuffer pStatementBuffer = new StringBuffer();
1872: pStatementBuffer.append("COMMENT ON COLUMN ");
1873: pStatementBuffer.append(lTableName);
1874: pStatementBuffer.append(".");
1875: pStatementBuffer.append(lRoleBColumnName);
1876: pStatementBuffer.append(" IS 'Association role ");
1877: pStatementBuffer.append(lRoleB.getName());
1878: pStatementBuffer.append(" : ");
1879: String lDescription = lRoleB.getDescription();
1880: if (lDescription == null
1881: || lDescription.trim().length() == 0)
1882: lDescription = "Description is missing from the model";
1883: else
1884: lDescription = "\" "
1885: + StringUtils.replace(lDescription,
1886: "'", "''") + " \"";
1887: pStatementBuffer.append(lDescription);
1888: pStatementBuffer.append(".';");
1889: lStatements.add(pStatementBuffer.toString());
1890: }
1891: }
1892: return (String[]) lStatements
1893: .toArray(new String[lStatements.size()]);
1894: } catch (JmiException e) {
1895: throw new BSServiceProviderException(e);
1896: }
1897: }
1898:
1899: protected void writeStatements(Writer pWriter, String[] pStatements)
1900: throws java.io.IOException {
1901: if (pStatements != null) {
1902: for (int i = 0; i < pStatements.length; i++) {
1903: pWriter.write(pStatements[i] + "\r\n");
1904: }
1905: pWriter.flush();
1906: }
1907: }
1908:
1909: // Generate table level coments
1910: protected String[] generateTableComment(Entity pEntity,
1911: DomainRelationalStorageDefinition pDomainStorage) {
1912: RelationalEntityTable lEntityTable = pDomainStorage
1913: .getEntityTable(pEntity);
1914: String lEntityTableName = lEntityTable.getNameOverride();
1915: if (lEntityTableName == null || lEntityTableName.length() == 0)
1916: lEntityTableName = lEntityTable.getNameSuggestion();
1917:
1918: // Build statement on a fly
1919: StringBuffer pStatementBuffer = new StringBuffer();
1920: pStatementBuffer.append("COMMENT ON TABLE ");
1921: pStatementBuffer.append(lEntityTableName);
1922: pStatementBuffer.append(" IS 'Entity ");
1923: pStatementBuffer.append(pEntity.getName());
1924: pStatementBuffer.append(" : ");
1925: String lDescription = pEntity.getDescription();
1926: if (lDescription == null || lDescription.trim().length() == 0)
1927: lDescription = "Description is missing from the model";
1928: else
1929: lDescription = "\" "
1930: + StringUtils.replace(lDescription, "'", "''")
1931: + " \"";
1932: pStatementBuffer.append(lDescription);
1933: pStatementBuffer.append(".';");
1934: return new String[] { pStatementBuffer.toString() };
1935: }
1936:
1937: // Generate table column level coments
1938: protected String[] generateTableColumnComments(Entity pEntity,
1939: DomainRelationalStorageDefinition pDomainStorage)
1940: throws BSException {
1941: RelationalEntityTable lEntityTable = pDomainStorage
1942: .getEntityTable(pEntity);
1943: String lEntityTableName = lEntityTable.getNameOverride();
1944: if (lEntityTableName == null || lEntityTableName.length() == 0)
1945: lEntityTableName = lEntityTable.getNameSuggestion();
1946: String lInstanceIdColumnName = lEntityTable
1947: .getInstanceIdColumnNameOverride();
1948: if (lInstanceIdColumnName == null
1949: || lInstanceIdColumnName.length() == 0)
1950: lInstanceIdColumnName = lEntityTable
1951: .getInstanceIdColumnNameSuggestion();
1952: String lEntityTableAlias = lEntityTable.getTableAlias();
1953:
1954: List lStatements = new ArrayList();
1955: {
1956: StringBuffer pStatementBuffer = new StringBuffer();
1957: pStatementBuffer.append("COMMENT ON COLUMN ");
1958: pStatementBuffer.append(lEntityTableName);
1959: pStatementBuffer.append(".");
1960: pStatementBuffer.append(lInstanceIdColumnName);
1961: pStatementBuffer
1962: .append(" IS 'Unique record id. Automatically generated by middleware just before new record is inserted.';");
1963: lStatements.add(pStatementBuffer.toString());
1964: }
1965: if (pEntity.isModifiable()) {
1966: String lVersionIdColumnName = lEntityTable
1967: .getVersionIdColumnNameOverride();
1968: if (lVersionIdColumnName == null
1969: || lVersionIdColumnName.length() == 0)
1970: lVersionIdColumnName = lEntityTable
1971: .getVersionIdColumnNameSuggestion();
1972:
1973: StringBuffer pStatementBuffer = new StringBuffer();
1974: pStatementBuffer.append("COMMENT ON COLUMN ");
1975: pStatementBuffer.append(lEntityTableName);
1976: pStatementBuffer.append(".");
1977: pStatementBuffer.append(lVersionIdColumnName);
1978: pStatementBuffer
1979: .append(" IS 'Record version id. Automatically incremented by middleware on every update to the record.';");
1980: lStatements.add(pStatementBuffer.toString());
1981: }
1982: if (pEntity.getStateMachine() != null) {
1983: String lStateColumnName = lEntityTable
1984: .getStateColumnNameOverride();
1985: if (lStateColumnName == null
1986: || lStateColumnName.length() == 0)
1987: lStateColumnName = lEntityTable
1988: .getVersionIdColumnNameSuggestion();
1989:
1990: StringBuffer pStatementBuffer = new StringBuffer();
1991: pStatementBuffer.append("COMMENT ON COLUMN ");
1992: pStatementBuffer.append(lEntityTableName);
1993: pStatementBuffer.append(".");
1994: pStatementBuffer.append(lStateColumnName);
1995: pStatementBuffer
1996: .append(" IS 'Entity state. Valid states are defined in the model.';");
1997: lStatements.add(pStatementBuffer.toString());
1998: }
1999: for (Iterator lAttributesIterator = pEntity.getAttributes()
2000: .iterator(); lAttributesIterator.hasNext();) {
2001: Attribute lAttribute = (Attribute) lAttributesIterator
2002: .next();
2003:
2004: RelationalEntityTableAttributeColumn lRelationalEntityTableAttribute = lEntityTable
2005: .getAttributeColumn(lAttribute);
2006: String lAttributeColumnName = lRelationalEntityTableAttribute
2007: .getColumnNameOverride();
2008: if (lAttributeColumnName == null
2009: || lAttributeColumnName.length() == 0)
2010: lAttributeColumnName = lRelationalEntityTableAttribute
2011: .getColumnNameSuggestion();
2012:
2013: StringBuffer pStatementBuffer = new StringBuffer();
2014: pStatementBuffer.append("COMMENT ON COLUMN ");
2015: pStatementBuffer.append(lEntityTableName);
2016: pStatementBuffer.append(".");
2017: pStatementBuffer.append(lAttributeColumnName);
2018: pStatementBuffer.append(" IS '");
2019: pStatementBuffer.append(lAttribute.getName());
2020: pStatementBuffer.append(" : ");
2021: String lDescription = lAttribute.getDescription();
2022: if (lDescription == null
2023: || lDescription.trim().length() == 0)
2024: lDescription = "Description is missing from the model";
2025: else
2026: lDescription = "\" "
2027: + StringUtils.replace(lDescription, "'", "''")
2028: + " \"";
2029: pStatementBuffer.append(lDescription);
2030: pStatementBuffer.append(".';");
2031: lStatements.add(pStatementBuffer.toString());
2032: }
2033: // Deal with associations
2034: for (Iterator lReferencesIterator = pEntity.getReferences()
2035: .iterator(); lReferencesIterator.hasNext();) {
2036: AssociationRole lReference = (AssociationRole) lReferencesIterator
2037: .next();
2038: // Reference column is only necessary if this entity has a reference
2039: if (CommonUtil.doesEntityStoreReference(lReference)) {
2040: RelationalEntityTableReferenceColumn lRelationalEntityTableAssociationRole = lEntityTable
2041: .getReferenceColumn(lReference);
2042: String lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
2043: .getColumnNameOverride();
2044: if (lAssociationRoleInstanceIdColumnName == null
2045: || lAssociationRoleInstanceIdColumnName
2046: .length() == 0)
2047: lAssociationRoleInstanceIdColumnName = lRelationalEntityTableAssociationRole
2048: .getColumnNameSuggestion();
2049:
2050: StringBuffer pStatementBuffer = new StringBuffer();
2051: pStatementBuffer.append("COMMENT ON COLUMN ");
2052: pStatementBuffer.append(lEntityTableName);
2053: pStatementBuffer.append(".");
2054: pStatementBuffer
2055: .append(lAssociationRoleInstanceIdColumnName);
2056: pStatementBuffer.append(" IS 'Reference ");
2057: pStatementBuffer.append(lReference.getName());
2058: pStatementBuffer.append(" : ");
2059: String lDescription = lReference.getAssociation()
2060: .getDescription();
2061: if (lDescription == null
2062: || lDescription.trim().length() == 0)
2063: lDescription = "Description is missing from the model";
2064: else
2065: lDescription = "\" "
2066: + StringUtils.replace(lDescription, "'",
2067: "''") + " \"";
2068: pStatementBuffer.append(lDescription);
2069: pStatementBuffer.append(".';");
2070: lStatements.add(pStatementBuffer.toString());
2071: }
2072: }
2073: return (String[]) lStatements.toArray(new String[lStatements
2074: .size()]);
2075: }
2076: }
|