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.metadatamanagement.domainstoragemanagement;
0016:
0017: import java.util.Collection;
0018: import java.util.HashMap;
0019: import java.util.HashSet;
0020: import java.util.Iterator;
0021: import java.util.List;
0022: import java.util.Map;
0023: import java.util.Properties;
0024: import java.util.Set;
0025:
0026: import javax.jmi.reflect.JmiException;
0027: import javax.naming.Context;
0028: import javax.naming.InitialContext;
0029: import javax.naming.NamingException;
0030:
0031: import org.apache.commons.logging.Log;
0032: import org.apache.commons.logging.LogFactory;
0033:
0034: import com.metaboss.enterprise.bo.BOException;
0035: import com.metaboss.enterprise.bo.BOUnexpectedProgramConditionException;
0036: import com.metaboss.enterprise.bs.BSDomainObjectInvocationException;
0037: import com.metaboss.enterprise.bs.BSException;
0038: import com.metaboss.enterprise.bs.BSNamingAndDirectoryServiceInvocationException;
0039: import com.metaboss.enterprise.bs.BSServiceProviderException;
0040: import com.metaboss.enterprise.bs.BSUnexpectedProgramConditionException;
0041: import com.metaboss.sdlctools.models.ModelRepository;
0042: import com.metaboss.sdlctools.models.metabossmodel.MetaBossModelPackage;
0043: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.AbstractNamespace;
0044: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataDictionary;
0045: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
0046: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataTypeUtils;
0047: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.Namespace;
0048: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.TypeTemplate;
0049: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.Enterprise;
0050: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Association;
0051: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.AssociationRole;
0052: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Attribute;
0053: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Domain;
0054: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.Entity;
0055: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainImplementationModelPackage;
0056: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainRelationalStorageDefinition;
0057: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.DomainRelationalStorageDefinitionClass;
0058: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalAssociationTable;
0059: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalAssociationTableClass;
0060: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTable;
0061: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableAttributeColumn;
0062: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableAttributeColumnClass;
0063: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableClass;
0064: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableReferenceColumn;
0065: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalEntityTableReferenceColumnClass;
0066: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalReferenceTable;
0067: import com.metaboss.sdlctools.models.metabossmodel.enterprisemodel.systemimplementationmodel.domainimplementationmodel.RelationalReferenceTableClass;
0068: import com.metaboss.sdlctools.models.metabossmodel.technologylibrarymodel.NameConversionType;
0069: import com.metaboss.sdlctools.models.metabossmodel.technologylibrarymodel.NameConversionTypeEnum;
0070: import com.metaboss.sdlctools.models.metabossmodel.technologylibrarymodel.RelationalStorageTechnology;
0071: import com.metaboss.sdlctools.services.codegeneration.CommonUtil;
0072: import com.metaboss.sdlctools.services.codegenerationstylesheet.BSCodeGenerationStylesheet;
0073: import com.metaboss.sdlctools.services.codegenerationstylesheet.STEntityStylesheet;
0074: import com.metaboss.util.StringUtils;
0075:
0076: // The only implementation we can think of at the moment
0077: public class RelationalDomainStorageManagement {
0078: // Commons Logging instance.
0079: private static final Log sLogger = LogFactory
0080: .getLog(RelationalDomainStorageManagement.class);
0081:
0082: // Special utility class gives back aliases for the table names. Guarantees to give back unique alias in the same run of jvm
0083: // Alias is a two letter or more acronim combination used as a shorthand for the table name
0084: // Two letters are used, so single letter aliases can be used for subqueries or any other
0085: // SQL token other than table alias.
0086: private static class TableAliases {
0087: private Set mAlreadyAssignedAliases = new HashSet();
0088: private Map mAliasesByRef = new HashMap();
0089:
0090: // Register the alias for the given ref
0091: // Throws exception if this ref has already been registered or this alias has already been used
0092: public void registerAlias(String pElementRef, String pAlias)
0093: throws BSException {
0094: if (mAliasesByRef.containsKey(pElementRef))
0095: throw new BSUnexpectedProgramConditionException(
0096: "Attempt is made to register an alias for the same element for the second time. ElementRef: "
0097: + pElementRef);
0098: if (mAlreadyAssignedAliases.contains(pAlias))
0099: throw new BSUnexpectedProgramConditionException(
0100: "Attempt is made to reuse same alias twice. Alias: "
0101: + pAlias);
0102: mAliasesByRef.put(pElementRef, pAlias);
0103: mAlreadyAssignedAliases.add(pAlias);
0104: }
0105:
0106: // Unregisters existing alias, which makes it avaialabe for reuse
0107: public void unregisterAlias(String pElementRef) {
0108: String lAlias = (String) mAliasesByRef.remove(pElementRef);
0109: if (lAlias != null)
0110: mAlreadyAssignedAliases.remove(lAlias);
0111: }
0112:
0113: // Gives out new or existing, unique alias
0114: public String getAlias(String pElementRef) {
0115: String lAlias = (String) mAliasesByRef.get(pElementRef);
0116: if (lAlias == null) {
0117: // Come up with the new alias and remember it for the future
0118: for (int i = 0;; i++) {
0119: // Express alias in radix 26 (number of letters in english alphabet
0120: // after that replace the 0,1,2,3,4,5,6,7,8,9 with Q,R,S,T,U,V,W,X,Y,Z
0121: // This is done so numbers are not part of the alias. Also aliases are shifted by 26
0122: // so the very first alias should be 'RQ' - which means '10' in the radix 26
0123: lAlias = Integer.toString(i + 26, 26).toLowerCase();
0124: lAlias = StringUtils.replace(lAlias, '0', "q");
0125: lAlias = StringUtils.replace(lAlias, '1', "r");
0126: lAlias = StringUtils.replace(lAlias, '2', "s");
0127: lAlias = StringUtils.replace(lAlias, '3', "t");
0128: lAlias = StringUtils.replace(lAlias, '4', "u");
0129: lAlias = StringUtils.replace(lAlias, '5', "v");
0130: lAlias = StringUtils.replace(lAlias, '6', "w");
0131: lAlias = StringUtils.replace(lAlias, '7', "x");
0132: lAlias = StringUtils.replace(lAlias, '8', "y");
0133: lAlias = StringUtils.replace(lAlias, '9', "z");
0134: // Only succeed if this alias is not used yet
0135: if (mAlreadyAssignedAliases.add(lAlias))
0136: break;
0137: }
0138: mAliasesByRef.put(pElementRef, lAlias);
0139: }
0140: return lAlias;
0141: }
0142: }
0143:
0144: // Updates metadata describing domain storage at the particular technology.
0145: public static void updateMetadataForDomain(
0146: RelationalStorageTechnology pStorageTechnology,
0147: String pDomainRef, String pReferenceModelName)
0148: throws BSException {
0149: try {
0150: // Get the referenced objects from the model
0151: Context lContext = new InitialContext();
0152: ModelRepository lModelRepository = (ModelRepository) lContext
0153: .lookup(ModelRepository.COMPONENT_URL);
0154: MetaBossModelPackage lMetaBossModelPackage = (MetaBossModelPackage) lModelRepository
0155: .getDefaultModelExtent();
0156: MetaBossModelPackage lMetaBossReferenceModelPackage = (pReferenceModelName != null) ? (MetaBossModelPackage) lModelRepository
0157: .getModelExtent(pReferenceModelName)
0158: : null;
0159: Domain lDomain = (Domain) lMetaBossModelPackage
0160: .getModelElement().getByRef(pDomainRef);
0161: BSCodeGenerationStylesheet lCodeGenerationStylesheet = (BSCodeGenerationStylesheet) lContext
0162: .lookup(BSCodeGenerationStylesheet.COMPONENT_URL);
0163: DomainRelationalStorageDefinition lDomainStorage = pStorageTechnology
0164: .findDomainImplementationDefinition(lDomain);
0165: if (lDomainStorage == null) {
0166: // Create the new one and add it to the domain
0167: DomainRelationalStorageDefinitionClass lDomainStorageClass = lMetaBossModelPackage
0168: .getEnterpriseModel()
0169: .getSystemImplementationModel()
0170: .getDomainImplementationModel()
0171: .getDomainRelationalStorageDefinition();
0172: lDomainStorage = lDomainStorageClass
0173: .createDomainRelationalStorageDefinition();
0174: lDomainStorage.setName(pStorageTechnology.getName());
0175: lDomainStorage
0176: .setDescription("Definition of the domain storage implementation using particular technology.");
0177: lDomainStorage.setTechnology(pStorageTechnology);
0178: lDomain.getRelationalImplementations().add(
0179: lDomainStorage);
0180: }
0181:
0182: // Check if we have the reference element, we will need to use it for the aliases
0183: // This assists with maintaining exact same aliases across releases.
0184: // Latter on we migh do the same with name suggestions
0185: DomainRelationalStorageDefinition lReferenceDomainRelationalStorageDefinition = (lMetaBossReferenceModelPackage != null) ? (DomainRelationalStorageDefinition) lMetaBossReferenceModelPackage
0186: .getModelElement().findByRef(
0187: lDomainStorage.getRef())
0188: : null;
0189: // Populate existing aliases (use reference domain storage definition if available)
0190: TableAliases lAliases = lReferenceDomainRelationalStorageDefinition != null ? getExistingAliases(lReferenceDomainRelationalStorageDefinition)
0191: : getExistingAliases(lDomainStorage);
0192:
0193: // List of table names must be unique within storage
0194: HashSet lTableNamespace = new HashSet();
0195: // List of constraints must be unique within storage
0196: HashSet lConstraintNamespace = new HashSet();
0197: // Update entity tables
0198: updateMetadataForEntities(lTableNamespace,
0199: lConstraintNamespace, lAliases, pStorageTechnology,
0200: lDomainStorage, lDomain);
0201: // Update associations
0202: updateMetadataForAssociations(lTableNamespace,
0203: lConstraintNamespace, lAliases, pStorageTechnology,
0204: lDomainStorage, lDomain);
0205: // Update references
0206: updateMetadataForReferences(lTableNamespace,
0207: lConstraintNamespace, lAliases, pStorageTechnology,
0208: lDomainStorage, lDomain);
0209: } catch (NamingException e) {
0210: throw new BSNamingAndDirectoryServiceInvocationException(e);
0211: } catch (BOException e) {
0212: throw new BSDomainObjectInvocationException(
0213: "Exception caught during updating of relational domain storage metadata.",
0214: e);
0215: }
0216: }
0217:
0218: // Helper. Updates entity tables metadata
0219: private static void updateMetadataForEntities(
0220: HashSet pTableNamespace, HashSet pConstraintNamespace,
0221: TableAliases pTableAliases,
0222: RelationalStorageTechnology pTechnology,
0223: DomainRelationalStorageDefinition pDomainStorage,
0224: Domain pDomain) throws BSException {
0225: try {
0226: // Set up class objects, which will be used to create instances
0227: RelationalEntityTableClass lEntityTableClass = ((DomainImplementationModelPackage) pDomainStorage
0228: .refImmediatePackage()).getRelationalEntityTable();
0229: RelationalEntityTableAttributeColumnClass lEntityTableAttributeColumnClass = ((DomainImplementationModelPackage) pDomainStorage
0230: .refImmediatePackage())
0231: .getRelationalEntityTableAttributeColumn();
0232: RelationalEntityTableReferenceColumnClass lEntityTableReferenceColumnClass = ((DomainImplementationModelPackage) pDomainStorage
0233: .refImmediatePackage())
0234: .getRelationalEntityTableReferenceColumn();
0235: // Setup typetemplates necessary for the datatypes
0236: Enterprise lEnterprise = pDomain.getSystem()
0237: .getEnterprise();
0238: DataDictionary lCoreDataDictionary = lEnterprise
0239: .getDesignLibrary().getDataDictionary("core");
0240: TypeTemplate lEnumerableValueTypeTemplate = lCoreDataDictionary
0241: .getTypeTemplate("EnumerableValueField");
0242:
0243: // Obtain stylesheet service
0244: Context lContext = new InitialContext();
0245: BSCodeGenerationStylesheet lCodeGenerationStylesheet = (BSCodeGenerationStylesheet) lContext
0246: .lookup(BSCodeGenerationStylesheet.COMPONENT_URL);
0247:
0248: // Note that we will be editing content, not overwriting them
0249: // so manual adjustments are preserved, removed entity tables will be deleted at the end
0250: Collection lEntityTables = pDomainStorage.getEntityTables();
0251: // Put collection of tables aside, so we can keep track of processed ones and the ones need to be deleted
0252: Map lUnprocessedEntityTables = new HashMap();
0253: for (Iterator lEntityTablesIterator = lEntityTables
0254: .iterator(); lEntityTablesIterator.hasNext();) {
0255: RelationalEntityTable lEntityTable = (RelationalEntityTable) lEntityTablesIterator
0256: .next();
0257: lUnprocessedEntityTables.put(lEntityTable.getEntity(),
0258: lEntityTable);
0259: }
0260: // Now go through entities updating what we have and creating new ones if necessary
0261: Collection lEntities = pDomain.getEntities();
0262: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0263: .hasNext();) {
0264: Entity lEntity = (Entity) lEntitiesIterator.next();
0265:
0266: // List of names must be unique within entity
0267: HashSet lColumnNamespace = new HashSet();
0268:
0269: BSCodeGenerationStylesheet.STGetEntityStylesheetInput lInput = new BSCodeGenerationStylesheet.STGetEntityStylesheetInput();
0270: lInput.setEntityRef(lEntity.getRef());
0271: STEntityStylesheet lEntityStylesheet = lCodeGenerationStylesheet
0272: .getEntityStylesheet(lInput).getStylesheet();
0273: if (lEntityStylesheet == null)
0274: throw new BOUnexpectedProgramConditionException(
0275: "Entity styleshet not found. EntityRef : "
0276: + lEntity.getRef());
0277: RelationalEntityTable lEntityTable = (RelationalEntityTable) lUnprocessedEntityTables
0278: .remove(lEntity);
0279: boolean lCreatingNewEntityTableRecord = false;
0280: if (lEntityTable == null) {
0281: // Create the new one and add it to the domain
0282: lEntityTable = lEntityTableClass
0283: .createRelationalEntityTable();
0284: lEntityTable.setName(lEntity.getName());
0285: lEntityTable
0286: .setDescription("Definition of the table where entity instances are stored.");
0287: lEntityTable.setEntity(lEntity);
0288: lEntityTables.add(lEntityTable);
0289: lCreatingNewEntityTableRecord = true;
0290: } else {
0291: lCreatingNewEntityTableRecord = false;
0292: }
0293: // Always refresh the name as it might have changed
0294: lEntityTable.setName(lEntity.getName());
0295: // Always set alias again as it might have been regenerated
0296: lEntityTable.setTableAlias(pTableAliases
0297: .getAlias(lEntityTable.getRef()));
0298:
0299: // Come up with the table name
0300: lEntityTable.setNameSuggestion(generateName(
0301: pTableNamespace, lEntity.getName(), pTechnology
0302: .getEntityTableNameConversionType(),
0303: pTechnology.getEntityTableNamePrefix(),
0304: pTechnology.getEntityTableNameSuffix(),
0305: pTechnology.getMaxTableNameLength()));
0306: // Come up with the instance id name
0307: lEntityTable
0308: .setInstanceIdColumnNameSuggestion(generateName(
0309: lColumnNamespace,
0310: pTechnology
0311: .getEntityInstanceIdColumnName(),
0312: NameConversionTypeEnum.NONE, "", "",
0313: pTechnology.getMaxColumnNameLength()));
0314: // Come up with version id name if necessary
0315: {
0316: if (lEntity.isModifiable()) {
0317: lEntityTable.setHasVersionIdColumn(true);
0318: lEntityTable
0319: .setVersionIdColumnNameSuggestion(generateName(
0320: lColumnNamespace,
0321: pTechnology
0322: .getEntityVersionIdColumnName(),
0323: NameConversionTypeEnum.NONE,
0324: "",
0325: "",
0326: pTechnology
0327: .getMaxColumnNameLength()));
0328: } else
0329: lEntityTable.setHasVersionIdColumn(false);
0330: }
0331: // Come up with state column related constraints if necessary
0332: {
0333: if (lEntity.getStateMachine() != null) {
0334: lEntityTable.setHasStateColumn(true);
0335: lEntityTable
0336: .setStateColumnNameSuggestion(generateName(
0337: lColumnNamespace,
0338: pTechnology
0339: .getEntityStateColumnName(),
0340: NameConversionTypeEnum.NONE,
0341: "",
0342: "",
0343: pTechnology
0344: .getMaxColumnNameLength()));
0345: lEntityTable
0346: .setStateReferentialConstraintNameSuggestion(generateName(
0347: pConstraintNamespace,
0348: lEntity.getName()
0349: + "_"
0350: + pTechnology
0351: .getEntityStateColumnName(),
0352: pTechnology
0353: .getEntityAttributeRefConstraintNameConversionType(),
0354: pTechnology
0355: .getEntityAttributeRefConstraintNamePrefix(),
0356: pTechnology
0357: .getEntityAttributeRefConstraintNameSuffix(),
0358: pTechnology
0359: .getMaxConstraintNameLength()));
0360: } else
0361: lEntityTable.setHasStateColumn(false);
0362: }
0363: // Always has a primary key constraint
0364: lEntityTable
0365: .setPrimaryKeyConstraintNameSuggestion(generateName(
0366: lColumnNamespace,
0367: lEntity.getName(),
0368: pTechnology
0369: .getEntityPrimaryKeyConstraintNameConversionType(),
0370: pTechnology
0371: .getEntityPrimaryKeyConstraintNamePrefix(),
0372: pTechnology
0373: .getEntityPrimaryKeyConstraintNameSuffix(),
0374: pTechnology
0375: .getMaxConstraintNameLength()));
0376:
0377: // Come up with primary key constraint name if necessary
0378: {
0379: if (lEntity.getPrimaryKeyElements().size() > 0) {
0380: lEntityTable.setHasNaturalPrimaryKey(true);
0381: lEntityTable
0382: .setNaturalPrimaryKeyConstraintNameSuggestion(generateName(
0383: lColumnNamespace,
0384: lEntity.getName(),
0385: pTechnology
0386: .getEntityNaturalPrimaryKeyConstraintNameConversionType(),
0387: pTechnology
0388: .getEntityNaturalPrimaryKeyConstraintNamePrefix(),
0389: pTechnology
0390: .getEntityNaturalPrimaryKeyConstraintNameSuffix(),
0391: pTechnology
0392: .getMaxConstraintNameLength()));
0393: } else
0394: lEntityTable.setHasNaturalPrimaryKey(false);
0395: }
0396: // Come up with supertype constraint name if necessary
0397: {
0398: if (lEntity.getSupertype() != null) {
0399: lEntityTable.setHasSupertype(true);
0400: lEntityTable
0401: .setSupertypeConstraintNameSuggestion(generateName(
0402: lColumnNamespace,
0403: lEntity.getName(),
0404: pTechnology
0405: .getEntitySupertypeConstraintNameConversionType(),
0406: pTechnology
0407: .getEntitySupertypeConstraintNamePrefix(),
0408: pTechnology
0409: .getEntitySupertypeConstraintNameSuffix(),
0410: pTechnology
0411: .getMaxConstraintNameLength()));
0412: } else
0413: lEntityTable.setHasSupertype(false);
0414: }
0415: // Work on attributes
0416: {
0417: Collection lEntityTableAttributeColumns = lEntityTable
0418: .getAttributeColumns();
0419: HashMap lUnprocessedEntityTableAttributes = new HashMap();
0420: if (!lCreatingNewEntityTableRecord) {
0421: for (Iterator lEntityTableAttributeColumnsIterator = lEntityTableAttributeColumns
0422: .iterator(); lEntityTableAttributeColumnsIterator
0423: .hasNext();) {
0424: RelationalEntityTableAttributeColumn lEntityTableAttributeColumn = (RelationalEntityTableAttributeColumn) lEntityTableAttributeColumnsIterator
0425: .next();
0426: lUnprocessedEntityTableAttributes.put(
0427: lEntityTableAttributeColumn
0428: .getAttribute(),
0429: lEntityTableAttributeColumn);
0430: }
0431: }
0432: Collection lAttributes = lEntity.getAttributes();
0433: for (Iterator lAttributesIterator = lAttributes
0434: .iterator(); lAttributesIterator.hasNext();) {
0435: Attribute lAttribute = (Attribute) lAttributesIterator
0436: .next();
0437: RelationalEntityTableAttributeColumn lTableAttribute = (RelationalEntityTableAttributeColumn) lUnprocessedEntityTableAttributes
0438: .remove(lAttribute);
0439: if (lTableAttribute == null) {
0440: lTableAttribute = lEntityTableAttributeColumnClass
0441: .createRelationalEntityTableAttributeColumn();
0442: lTableAttribute
0443: .setDescription("Definition of the column where attribute value is stored.");
0444: lTableAttribute.setAttribute(lAttribute);
0445: lTableAttribute.setTable(lEntityTable);
0446: }
0447: // Always refresh the name as it might have changed
0448: lTableAttribute.setName(lAttribute.getName());
0449: lTableAttribute
0450: .setColumnNameSuggestion(generateName(
0451: lColumnNamespace,
0452: lAttribute.getName(),
0453: pTechnology
0454: .getAttributeColumnNameConversionType(),
0455: pTechnology
0456: .getAttributeColumnNamePrefix(),
0457: pTechnology
0458: .getAttributeColumnNameSuffix(),
0459: pTechnology
0460: .getMaxColumnNameLength()));
0461: // Work on possible constraint name
0462: DataType lAttributeDatatype = lAttribute
0463: .getDataType();
0464: TypeTemplate lTypetemplate = lAttributeDatatype
0465: .getTypetemplate();
0466: if (lTypetemplate != null
0467: && lTypetemplate
0468: .equals(lEnumerableValueTypeTemplate)) {
0469: lTableAttribute
0470: .setHasReferentialConstraint(true);
0471: lTableAttribute
0472: .setReferentialConstraintNameSuggestion(generateName(
0473: pConstraintNamespace,
0474: lEntity.getName()
0475: + "_"
0476: + lAttribute
0477: .getName(),
0478: pTechnology
0479: .getEntityAttributeRefConstraintNameConversionType(),
0480: pTechnology
0481: .getEntityAttributeRefConstraintNamePrefix(),
0482: pTechnology
0483: .getEntityAttributeRefConstraintNameSuffix(),
0484: pTechnology
0485: .getMaxConstraintNameLength()));
0486: } else
0487: lTableAttribute
0488: .setHasReferentialConstraint(false);
0489: }
0490: // Now delete all unprocessed attributes - means that the entities are not present
0491: for (Iterator lUnprocessedEntityTableAttributesIter = lUnprocessedEntityTableAttributes
0492: .values().iterator(); lUnprocessedEntityTableAttributesIter
0493: .hasNext();) {
0494: RelationalEntityTableAttributeColumn lEntityTableAttributeColumn = (RelationalEntityTableAttributeColumn) lUnprocessedEntityTableAttributesIter
0495: .next();
0496: lEntityTableAttributeColumn.refDelete();
0497: }
0498: }
0499: // Work on reference columns
0500: {
0501: Collection lEntityTableReferenceColumns = lEntityTable
0502: .getReferenceColumns();
0503: HashMap lUnprocessedEntityTableReferences = new HashMap();
0504: if (!lCreatingNewEntityTableRecord) {
0505: for (Iterator lEntityTableReferenceColumnsIterator = lEntityTableReferenceColumns
0506: .iterator(); lEntityTableReferenceColumnsIterator
0507: .hasNext();) {
0508: RelationalEntityTableReferenceColumn lEntityTableReferenceColumn = (RelationalEntityTableReferenceColumn) lEntityTableReferenceColumnsIterator
0509: .next();
0510: lUnprocessedEntityTableReferences.put(
0511: lEntityTableReferenceColumn
0512: .getAssociationRole(),
0513: lEntityTableReferenceColumn);
0514: }
0515: }
0516: Collection lReferences = lEntity.getReferences();
0517: for (Iterator lReferencesIterator = lReferences
0518: .iterator(); lReferencesIterator.hasNext();) {
0519: AssociationRole lReference = (AssociationRole) lReferencesIterator
0520: .next();
0521: Association lAssociation = lReference
0522: .getAssociation();
0523: // Reference column is only necessary if this entity has a reference
0524: if (CommonUtil
0525: .doesEntityStoreReference(lReference)) {
0526: RelationalEntityTableReferenceColumn lTableAssociationRole = (RelationalEntityTableReferenceColumn) lUnprocessedEntityTableReferences
0527: .remove(lReference);
0528: if (lTableAssociationRole == null) {
0529: lTableAssociationRole = lEntityTableReferenceColumnClass
0530: .createRelationalEntityTableReferenceColumn();
0531: lTableAssociationRole
0532: .setDescription("Definition of the column where reference to another entity is stored.");
0533: lTableAssociationRole
0534: .setAssociationRole(lReference);
0535: lTableAssociationRole
0536: .setTable(lEntityTable);
0537: }
0538: // Always refresh the name as it might have changed
0539: lTableAssociationRole.setName(lReference
0540: .getName());
0541: lTableAssociationRole
0542: .setColumnNameSuggestion(generateName(
0543: lColumnNamespace,
0544: lReference.getName(),
0545: pTechnology
0546: .getAssociationRoleColumnNameConversionType(),
0547: pTechnology
0548: .getAssociationRoleColumnNamePrefix(),
0549: pTechnology
0550: .getAssociationRoleColumnNameSuffix(),
0551: pTechnology
0552: .getMaxColumnNameLength()));
0553: lTableAssociationRole
0554: .setReferentialConstraintNameSuggestion(generateName(
0555: pConstraintNamespace,
0556: lReference.getName()
0557: + "From"
0558: + lAssociation
0559: .getName(),
0560: pTechnology
0561: .getAssociationRoleReferentialConstraintNameConversionType(),
0562: pTechnology
0563: .getAssociationRoleReferentialConstraintNamePrefix(),
0564: pTechnology
0565: .getAssociationRoleReferentialConstraintNameSuffix(),
0566: pTechnology
0567: .getMaxConstraintNameLength()));
0568: }
0569: }
0570: // Now delete all unprocessed references because corresponding roles are not present
0571: for (Iterator lUnprocessedEntityTableReferencesIter = lUnprocessedEntityTableReferences
0572: .values().iterator(); lUnprocessedEntityTableReferencesIter
0573: .hasNext();) {
0574: RelationalEntityTableAttributeColumn lEntityTableReferenceColumn = (RelationalEntityTableAttributeColumn) lUnprocessedEntityTableReferencesIter
0575: .next();
0576: lEntityTableReferenceColumn.refDelete();
0577: }
0578: }
0579:
0580: }
0581: // Now delete all unprocessed entities because corresponding entities are not present
0582: for (Iterator lUnprocessedEntityTablesIter = lUnprocessedEntityTables
0583: .values().iterator(); lUnprocessedEntityTablesIter
0584: .hasNext();) {
0585: RelationalEntityTable lEntityTable = (RelationalEntityTable) lUnprocessedEntityTablesIter
0586: .next();
0587: pTableAliases.unregisterAlias(lEntityTable.getRef());
0588: lEntityTable.refDelete();
0589: }
0590: } catch (NamingException e) {
0591: throw new BSNamingAndDirectoryServiceInvocationException(e);
0592: } catch (BOException e) {
0593: throw new BSDomainObjectInvocationException(
0594: "Exception caught during updating of storage metadata.",
0595: e);
0596: }
0597: }
0598:
0599: // Helper. Updates asociation tables metadata
0600: private static void updateMetadataForAssociations(
0601: HashSet pTableNamespace, HashSet pConstraintNamespace,
0602: TableAliases pTableAliases,
0603: RelationalStorageTechnology pTechnology,
0604: DomainRelationalStorageDefinition pDomainStorage,
0605: Domain pDomain) throws BSException {
0606: try {
0607: // Set up class objects, which will be used to create instances
0608: RelationalAssociationTableClass lAssociationTableClass = ((DomainImplementationModelPackage) pDomainStorage
0609: .refImmediatePackage())
0610: .getRelationalAssociationTable();
0611: // Obtain stylesheet service
0612: Context lContext = new InitialContext();
0613: BSCodeGenerationStylesheet lCodeGenerationStylesheet = (BSCodeGenerationStylesheet) lContext
0614: .lookup(BSCodeGenerationStylesheet.COMPONENT_URL);
0615:
0616: // Note that we will be editing content, not overwriting them
0617: // so manual adjustments are preserved, removed reference tables will be deleted at the end
0618: // First build list of known entity tables, so we can remove the extra ones at the end
0619: Collection lAssociationTables = pDomainStorage
0620: .getAssociationTables();
0621: HashMap lUnprocessedAssociationTables = new HashMap();
0622: for (Iterator lAssociationTablesIterator = lAssociationTables
0623: .iterator(); lAssociationTablesIterator.hasNext();) {
0624: RelationalAssociationTable lAssociationTable = (RelationalAssociationTable) lAssociationTablesIterator
0625: .next();
0626: lUnprocessedAssociationTables.put(lAssociationTable
0627: .getAssociation(), lAssociationTable);
0628: }
0629: // Now go through entities updating what we have and creating new ones if necessary
0630: Collection lAssociations = pDomain.getAssociations();
0631: for (Iterator lAssociationsIterator = lAssociations
0632: .iterator(); lAssociationsIterator.hasNext();) {
0633: Association lAssociation = (Association) lAssociationsIterator
0634: .next();
0635: // First make a decision if we have this association table at all
0636: if (CommonUtil.doEntitiesStoreReference(lAssociation))
0637: continue; // One of the sides of the association has a reference - no need for a table
0638: List lRoles = lAssociation.getRoles();
0639: AssociationRole lRoleA = (AssociationRole) lRoles
0640: .get(0);
0641: AssociationRole lRoleB = (AssociationRole) lRoles
0642: .get(1);
0643: // List of names must be unique within entity
0644: HashSet lColumnNamespace = new HashSet();
0645:
0646: RelationalAssociationTable lAssociationTable = (RelationalAssociationTable) lUnprocessedAssociationTables
0647: .remove(lAssociation);
0648: if (lAssociationTable == null) {
0649: lAssociationTable = lAssociationTableClass
0650: .createRelationalAssociationTable();
0651: lAssociationTable
0652: .setDescription("Definition of the table where association between two entities is stored.");
0653: lAssociationTable.setAssociation(lAssociation);
0654: lAssociationTables.add(lAssociationTable);
0655: }
0656: // Always refresh the name as it might have changed
0657: lAssociationTable.setName(lAssociation.getName());
0658: // Always set alias again as it might have been regenerated
0659: lAssociationTable.setTableAlias(pTableAliases
0660: .getAlias(lAssociationTable.getRef()));
0661:
0662: // Come up with the table name
0663: lAssociationTable
0664: .setNameSuggestion(generateName(
0665: pTableNamespace,
0666: lAssociation.getName(),
0667: pTechnology
0668: .getAssociationTableNameConversionType(),
0669: pTechnology
0670: .getAssociationTableNamePrefix(),
0671: pTechnology
0672: .getAssociationTableNameSuffix(),
0673: pTechnology.getMaxTableNameLength()));
0674: // Come up with the role a column name
0675: lAssociationTable
0676: .setFirstRoleColumnNameSuggestion(generateName(
0677: lColumnNamespace,
0678: lRoleA.getName(),
0679: pTechnology
0680: .getAssociationRoleColumnNameConversionType(),
0681: pTechnology
0682: .getAssociationRoleColumnNamePrefix(),
0683: pTechnology
0684: .getAssociationRoleColumnNameSuffix(),
0685: pTechnology.getMaxColumnNameLength()));
0686: // Come up with the role a constraint name
0687: lAssociationTable
0688: .setFirstRoleReferentialConstraintNameSuggestion(generateName(
0689: pConstraintNamespace,
0690: lRoleA.getName() + "From"
0691: + lAssociation.getName(),
0692: pTechnology
0693: .getAssociationRoleReferentialConstraintNameConversionType(),
0694: pTechnology
0695: .getAssociationRoleReferentialConstraintNamePrefix(),
0696: pTechnology
0697: .getAssociationRoleReferentialConstraintNameSuffix(),
0698: pTechnology
0699: .getMaxConstraintNameLength()));
0700: // Come up with the role b column name
0701: lAssociationTable
0702: .setSecondRoleColumnNameSuggestion(generateName(
0703: lColumnNamespace,
0704: lRoleB.getName(),
0705: pTechnology
0706: .getAssociationRoleColumnNameConversionType(),
0707: pTechnology
0708: .getAssociationRoleColumnNamePrefix(),
0709: pTechnology
0710: .getAssociationRoleColumnNameSuffix(),
0711: pTechnology.getMaxColumnNameLength()));
0712: // Come up with the role b constraint name
0713: lAssociationTable
0714: .setSecondRoleReferentialConstraintNameSuggestion(generateName(
0715: pConstraintNamespace,
0716: lRoleB.getName() + "From"
0717: + lAssociation.getName(),
0718: pTechnology
0719: .getAssociationRoleReferentialConstraintNameConversionType(),
0720: pTechnology
0721: .getAssociationRoleReferentialConstraintNamePrefix(),
0722: pTechnology
0723: .getAssociationRoleReferentialConstraintNameSuffix(),
0724: pTechnology
0725: .getMaxConstraintNameLength()));
0726: // Come up with the primary key constraint name
0727: lAssociationTable
0728: .setPrimaryKeyConstraintNameSuggestion(generateName(
0729: pConstraintNamespace,
0730: lAssociation.getName(),
0731: pTechnology
0732: .getAssociationPrimaryKeyConstraintNameConversionType(),
0733: pTechnology
0734: .getAssociationPrimaryKeyConstraintNamePrefix(),
0735: pTechnology
0736: .getAssociationPrimaryKeyConstraintNameSuffix(),
0737: pTechnology
0738: .getMaxConstraintNameLength()));
0739: }
0740: // Now delete all unprocessed entities - means that the entities are not present
0741: for (Iterator lUnprocessedAssociationTablesIter = lUnprocessedAssociationTables
0742: .values().iterator(); lUnprocessedAssociationTablesIter
0743: .hasNext();) {
0744: RelationalAssociationTable lAssociationTable = (RelationalAssociationTable) lUnprocessedAssociationTablesIter
0745: .next();
0746: pTableAliases.unregisterAlias(lAssociationTable
0747: .getRef());
0748: lAssociationTable.refDelete();
0749: }
0750: } catch (NamingException e) {
0751: throw new BSNamingAndDirectoryServiceInvocationException(e);
0752: } catch (JmiException e) {
0753: throw new BSServiceProviderException(
0754: "Exception caught during updating of storage metadata foir the entity tables.",
0755: e);
0756: }
0757: }
0758:
0759: // Helper. Updates asociation tables metadata
0760: private static void updateMetadataForReferences(
0761: HashSet pTableNamespace, HashSet pConstraintNamespace,
0762: TableAliases pTableAliases,
0763: RelationalStorageTechnology pTechnology,
0764: DomainRelationalStorageDefinition pDomainStorage,
0765: Domain pDomain) throws BSException {
0766: try {
0767: // Set up class objects, which will be used to create instances
0768: RelationalReferenceTableClass lReferenceTableClass = ((DomainImplementationModelPackage) pDomainStorage
0769: .refImmediatePackage())
0770: .getRelationalReferenceTable();
0771: // Setup typetemplates necessary for the datatypes
0772: Enterprise lEnterprise = pDomain.getSystem()
0773: .getEnterprise();
0774: DataDictionary lCoreDataDictionary = lEnterprise
0775: .getDesignLibrary().getDataDictionary("core");
0776: TypeTemplate lEnumerableValueTypeTemplate = lCoreDataDictionary
0777: .getTypeTemplate("EnumerableValueField");
0778:
0779: String lDefaultSystemPrefix = pDomain.getSystem().getRef();
0780: int lDefaultSystemPrefixLength = lDefaultSystemPrefix
0781: .length();
0782:
0783: Context lContext = new InitialContext();
0784: BSCodeGenerationStylesheet lCodeGenerationStylesheet = (BSCodeGenerationStylesheet) lContext
0785: .lookup(BSCodeGenerationStylesheet.COMPONENT_URL);
0786:
0787: // Note that we will be editing content, not overwriting them
0788: // so manual adjustments are preserved, removed reference tables will be deleted at the end
0789: // First build list of known entity tables, so we can remove the extra ones at the end
0790: Collection lReferenceTables = pDomainStorage
0791: .getReferenceTables();
0792: HashMap lUnprocessedlReferenceTables = new HashMap();
0793: for (Iterator lReferenceTablesIterator = lReferenceTables
0794: .iterator(); lReferenceTablesIterator.hasNext();) {
0795: RelationalReferenceTable lReferenceTable = (RelationalReferenceTable) lReferenceTablesIterator
0796: .next();
0797: lUnprocessedlReferenceTables.put(lReferenceTable
0798: .getDataType(), lReferenceTable);
0799: }
0800: // Work on enumerable types. They could be of two kinds :
0801: // pure enumerable types and states from the state machine
0802: // Go through entities and collect enumerables (could have duplicates)
0803: Set lEnumerableTypes = new HashSet();
0804: Collection lEntities = pDomain.getEntities();
0805: for (Iterator lEntitiesIterator = lEntities.iterator(); lEntitiesIterator
0806: .hasNext();) {
0807: Entity lEntity = (Entity) lEntitiesIterator.next();
0808: // See if we neeed to collect state reference type
0809: if (lEntity.getStateMachine() != null) {
0810: // Write reference table
0811: DataType lStateDatatype = lEntity
0812: .getStateDataType();
0813: if (!lEnumerableTypes.contains(lStateDatatype))
0814: lEnumerableTypes.add(lStateDatatype);
0815: }
0816: Collection lAttributes = lEntity.getAttributes();
0817: for (Iterator lAttributesIterator = lAttributes
0818: .iterator(); lAttributesIterator.hasNext();) {
0819: Attribute lAttribute = (Attribute) lAttributesIterator
0820: .next();
0821: DataType lAttributeDatatype = lAttribute
0822: .getDataType();
0823: if (!lEnumerableTypes.contains(lAttributeDatatype)) {
0824: TypeTemplate lTypetemplate = lAttributeDatatype
0825: .getTypetemplate();
0826: if (lTypetemplate != null
0827: && lTypetemplate
0828: .equals(lEnumerableValueTypeTemplate))
0829: lEnumerableTypes.add(lAttributeDatatype);
0830: }
0831: }
0832: }
0833: // Go through list of collected enumerable datatypes (they are unique now) and create reference table
0834: {
0835: for (Iterator lEnumerableTypesIter = lEnumerableTypes
0836: .iterator(); lEnumerableTypesIter.hasNext();) {
0837: DataType lDatatype = (DataType) lEnumerableTypesIter
0838: .next();
0839:
0840: // List of columns must be unique within table
0841: HashSet lColumnNamespace = new HashSet();
0842:
0843: RelationalReferenceTable lReferenceTable = (RelationalReferenceTable) lUnprocessedlReferenceTables
0844: .remove(lDatatype.getRef());
0845: if (lReferenceTable == null) {
0846: lReferenceTable = lReferenceTableClass
0847: .createRelationalReferenceTable();
0848: lReferenceTable
0849: .setDescription("Definition of the table where reference data for enumerable data types is stored.");
0850: lReferenceTable.setDataType(lDatatype);
0851: lReferenceTables.add(lReferenceTable);
0852: }
0853: // Always refresh the name as it might have changed
0854: lReferenceTable.setName(lDatatype.getName());
0855: // Always set alias again as it might have been regenerated
0856: lReferenceTable.setTableAlias(pTableAliases
0857: .getAlias(lReferenceTable.getRef()));
0858:
0859: // Do a little bit of work with datatype name
0860: // If datatype is from the same system no need to include enterprise and system prefixes
0861: // If datatype is from another system - include system name as well
0862: StringBuffer lDataTypeBaseName = new StringBuffer();
0863: DataDictionary lOwnerDataDictionary = lDatatype
0864: .getOwnerDataDictionary();
0865: lDataTypeBaseName.append(lDatatype.getName());
0866: for (AbstractNamespace lNamespace = lDatatype
0867: .getNamespace(); lNamespace instanceof Namespace; lNamespace = ((Namespace) lNamespace)
0868: .getNamespace()) {
0869: lDataTypeBaseName.append("_from_");
0870: lDataTypeBaseName.append(lNamespace.getName());
0871: }
0872: if (lOwnerDataDictionary.getDesignLibrary() != null) {
0873: lDataTypeBaseName.append("_from_Enterprise");
0874: } else if (!lOwnerDataDictionary.getSystem()
0875: .equals(pDomain.getSystem())) {
0876: lDataTypeBaseName.append("_from_");
0877: lDataTypeBaseName.append(lOwnerDataDictionary
0878: .getSystem().getName());
0879: lDataTypeBaseName.append("_System");
0880: }
0881: // Come up with the table name
0882: lReferenceTable
0883: .setNameSuggestion(generateName(
0884: pTableNamespace,
0885: lDataTypeBaseName.toString(),
0886: pTechnology
0887: .getReferenceTableNameConversionType(),
0888: pTechnology
0889: .getReferenceTableNamePrefix(),
0890: pTechnology
0891: .getReferenceTableNameSuffix(),
0892: pTechnology.getMaxTableNameLength()));
0893: // Come up with the primary key constraint name
0894: lReferenceTable
0895: .setPrimaryKeyConstraintNameSuggestion(generateName(
0896: pConstraintNamespace,
0897: lDataTypeBaseName.toString(),
0898: pTechnology
0899: .getReferencePrimaryKeyConstraintNameConversionType(),
0900: pTechnology
0901: .getReferencePrimaryKeyConstraintNamePrefix(),
0902: pTechnology
0903: .getReferencePrimaryKeyConstraintNameSuffix(),
0904: pTechnology
0905: .getMaxConstraintNameLength()));
0906: // Come up with the value column name
0907: lReferenceTable
0908: .setValueColumnNameSuggestion(generateName(
0909: lColumnNamespace,
0910: pTechnology
0911: .getReferenceValueColumnName(),
0912: NameConversionTypeEnum.NONE, "",
0913: "", pTechnology
0914: .getMaxColumnNameLength()));
0915: // Come up with the description column name
0916: lReferenceTable
0917: .setDescriptionColumnNameSuggestion(generateName(
0918: lColumnNamespace,
0919: pTechnology
0920: .getReferenceDescriptionColumnName(),
0921: NameConversionTypeEnum.NONE, "",
0922: "", pTechnology
0923: .getMaxColumnNameLength()));
0924: // Come up with weight column if necessary
0925: {
0926: // First we need to get all values and analyse things like column sizes, etc
0927: Properties lEnumerableTypetemplateProperties = DataTypeUtils
0928: .getTypetemplatePropertiesAsProperties(lDatatype);
0929: boolean lComparable = Boolean.valueOf(
0930: lEnumerableTypetemplateProperties
0931: .getProperty("Comparable",
0932: "false"))
0933: .booleanValue();
0934: if (lComparable) {
0935: lReferenceTable
0936: .setHasComparisonMechanism(true);
0937: lReferenceTable
0938: .setWeightColumnNameSuggestion(generateName(
0939: lColumnNamespace,
0940: pTechnology
0941: .getReferenceWeightColumnName(),
0942: NameConversionTypeEnum.NONE,
0943: "",
0944: "",
0945: pTechnology
0946: .getMaxColumnNameLength()));
0947: lReferenceTable
0948: .setWeightConstraintNameSuggestion(generateName(
0949: lColumnNamespace,
0950: lDataTypeBaseName
0951: .toString(),
0952: pTechnology
0953: .getReferenceWeightConstraintNameConversionType(),
0954: pTechnology
0955: .getReferenceWeightConstraintNamePrefix(),
0956: pTechnology
0957: .getReferenceWeightConstraintNameSuffix(),
0958: pTechnology
0959: .getMaxColumnNameLength()));
0960: } else
0961: lReferenceTable
0962: .setHasComparisonMechanism(false);
0963: }
0964: }
0965: }
0966: // Now delete all unprocessed entities - means that the entities are not present
0967: for (Iterator lUnprocessedReferenceTablesIter = lUnprocessedlReferenceTables
0968: .values().iterator(); lUnprocessedReferenceTablesIter
0969: .hasNext();) {
0970: RelationalReferenceTable lReferenceTable = (RelationalReferenceTable) lUnprocessedReferenceTablesIter
0971: .next();
0972: pTableAliases.unregisterAlias(lReferenceTable.getRef());
0973: lReferenceTable.refDelete();
0974: }
0975: } catch (NamingException e) {
0976: throw new BSNamingAndDirectoryServiceInvocationException(e);
0977: } catch (JmiException e) {
0978: throw new BSServiceProviderException(
0979: "Exception caught during updating of storage metadata.",
0980: e);
0981: }
0982: }
0983:
0984: // Helper. Returns aliases object populated with an existing aliases
0985: private static TableAliases getExistingAliases(
0986: DomainRelationalStorageDefinition pDomainStorage)
0987: throws BSException {
0988: try {
0989: TableAliases lReturnAliases = new TableAliases();
0990: // Entity tables
0991: Collection lEntityTables = pDomainStorage.getEntityTables();
0992: for (Iterator lEntityTablesIterator = lEntityTables
0993: .iterator(); lEntityTablesIterator.hasNext();) {
0994: RelationalEntityTable lEntityTable = (RelationalEntityTable) lEntityTablesIterator
0995: .next();
0996: lReturnAliases.registerAlias(lEntityTable.getRef(),
0997: lEntityTable.getTableAlias());
0998: }
0999: // Association tables
1000: Collection lAssociationTables = pDomainStorage
1001: .getAssociationTables();
1002: for (Iterator lAssociationTablesIterator = lAssociationTables
1003: .iterator(); lAssociationTablesIterator.hasNext();) {
1004: RelationalAssociationTable lAssociationTable = (RelationalAssociationTable) lAssociationTablesIterator
1005: .next();
1006: lReturnAliases.registerAlias(
1007: lAssociationTable.getRef(), lAssociationTable
1008: .getTableAlias());
1009: }
1010: // Reference tables
1011: Collection lReferenceTables = pDomainStorage
1012: .getReferenceTables();
1013: for (Iterator lReferenceTablesIterator = lReferenceTables
1014: .iterator(); lReferenceTablesIterator.hasNext();) {
1015: RelationalReferenceTable lReferenceTable = (RelationalReferenceTable) lReferenceTablesIterator
1016: .next();
1017: lReturnAliases.registerAlias(lReferenceTable.getRef(),
1018: lReferenceTable.getTableAlias());
1019: }
1020: return lReturnAliases;
1021: } catch (JmiException e) {
1022: throw new BSServiceProviderException(
1023: "Exception caught during updating of storage metadata.",
1024: e);
1025: }
1026: }
1027:
1028: private static final String sValves = "aeuioy";
1029:
1030: // Returns a good name - unique in the namespace. Updates namespace, so this name can not be reused
1031: private static String generateName(HashSet pNamespace,
1032: String pBaseName, NameConversionType pNameConversionType,
1033: String pPrefix, String pSuffix, int pMaxLength)
1034: throws BSException {
1035: StringBuffer lNameBuffer = new StringBuffer();
1036: // Prefix first
1037: lNameBuffer.append(pPrefix);
1038: // Perform conversion
1039: if (pNameConversionType.equals(NameConversionTypeEnum.UPPER))
1040: lNameBuffer.append(StringUtils.suggestName(pBaseName,
1041: false, false).toUpperCase());
1042: else if (pNameConversionType
1043: .equals(NameConversionTypeEnum.UPPER_UNDERSCORED))
1044: lNameBuffer.append(StringUtils
1045: .suggestConstantIdentifier(pBaseName));
1046: else if (pNameConversionType
1047: .equals(NameConversionTypeEnum.LOWER))
1048: lNameBuffer.append(StringUtils.suggestName(pBaseName,
1049: false, false).toLowerCase());
1050: else if (pNameConversionType
1051: .equals(NameConversionTypeEnum.LOWER_UNDERSCORED))
1052: lNameBuffer.append(StringUtils.suggestConstantIdentifier(
1053: pBaseName).toLowerCase());
1054: else
1055: // Simplest conversion - just to guard against spaces etc.
1056: lNameBuffer.append(StringUtils.suggestName(pBaseName,
1057: false, false));
1058: // Now suffix
1059: lNameBuffer.append(pSuffix);
1060: // At this point we have got a name - now we need to make sure it is unique and is within length limit
1061: String lModifiedName = lNameBuffer.toString();
1062: while ((lModifiedName.length() > pMaxLength)
1063: || (pNamespace.contains(lModifiedName))) {
1064: char[] lChars = lModifiedName.toCharArray();
1065: // Delete all separators (not letters or digits) starting from the back until length has been reached
1066: for (int i = lChars.length - 1; i >= 0; i--) {
1067: if (!Character.isLetterOrDigit(lChars[i])) {
1068: String lFrontPart = lModifiedName.substring(0, i);
1069: String lBackPart = (i < (lChars.length - 1)) ? lModifiedName
1070: .substring(i + 1)
1071: : "";
1072: lModifiedName = lFrontPart + lBackPart;
1073: break;
1074: }
1075: }
1076: if (lModifiedName.length() < lChars.length)
1077: continue; // Somethig was replaced
1078: // Delete all digits (not letters) starting from the back until length has been reached
1079: for (int i = lChars.length - 1; i >= 0; i--) {
1080: if (!Character.isLetter(lChars[i])) {
1081: String lFrontPart = lModifiedName.substring(0, i);
1082: String lBackPart = (i < (lChars.length - 1)) ? lModifiedName
1083: .substring(i + 1)
1084: : "";
1085: lModifiedName = lFrontPart + lBackPart;
1086: break;
1087: }
1088: }
1089: if (lModifiedName.length() < lChars.length)
1090: continue; // Somethig was replaced
1091: // Delete all valves starting from the back until length has been reached
1092: for (int i = lChars.length - 1; i >= 0; i--) {
1093: if (sValves.indexOf(lChars[i]) >= 0) {
1094: String lFrontPart = lModifiedName.substring(0, i);
1095: String lBackPart = (i < (lChars.length - 1)) ? lModifiedName
1096: .substring(i + 1)
1097: : "";
1098: lModifiedName = lFrontPart + lBackPart;
1099: break;
1100: }
1101: }
1102: if (lModifiedName.length() < lChars.length)
1103: continue; // Somethig was replaced
1104:
1105: // Length is within limit, but all the valves are gone
1106: // First make sure that length is at limit
1107: if (lModifiedName.length() > pMaxLength) {
1108: lModifiedName = lModifiedName.substring(0, pMaxLength);
1109: if (!pNamespace.contains(lModifiedName))
1110: break; // Chopped the stuff off and got out lucky
1111: }
1112: // Nothing more complex is implemented so far
1113: throw new BSUnexpectedProgramConditionException(
1114: "Unable to generate unique name for " + pBaseName);
1115: }
1116: pNamespace.add(lModifiedName);
1117: return lModifiedName;
1118: }
1119: }
|