/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ddl.importer.node; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.osgi.util.NLS; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.designer.core.ModelEditor; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.extension.AbstractMetaclassNameProvider; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.extension.ExtensionPlugin; import org.teiid.designer.extension.definition.ModelExtensionAssistant; import org.teiid.designer.extension.definition.ModelExtensionDefinition; import org.teiid.designer.extension.definition.ModelObjectExtensionAssistant; import org.teiid.designer.extension.properties.ModelExtensionPropertyDefinition; import org.teiid.designer.extension.registry.ModelExtensionRegistry; import org.teiid.designer.metamodels.core.Annotation; import org.teiid.designer.metamodels.core.AnnotationContainer; import org.teiid.designer.metamodels.core.CoreFactory; import org.teiid.designer.metamodels.relational.AccessPattern; import org.teiid.designer.metamodels.relational.BaseTable; import org.teiid.designer.metamodels.relational.Catalog; import org.teiid.designer.metamodels.relational.Column; import org.teiid.designer.metamodels.relational.DirectionKind; import org.teiid.designer.metamodels.relational.ForeignKey; import org.teiid.designer.metamodels.relational.Index; import org.teiid.designer.metamodels.relational.MultiplicityKind; import org.teiid.designer.metamodels.relational.NullableType; import org.teiid.designer.metamodels.relational.PrimaryKey; import org.teiid.designer.metamodels.relational.Procedure; import org.teiid.designer.metamodels.relational.ProcedureParameter; import org.teiid.designer.metamodels.relational.ProcedureResult; import org.teiid.designer.metamodels.relational.ProcedureUpdateCount; import org.teiid.designer.metamodels.relational.RelationalFactory; import org.teiid.designer.metamodels.relational.Schema; import org.teiid.designer.metamodels.relational.SearchabilityType; import org.teiid.designer.metamodels.relational.Table; import org.teiid.designer.metamodels.relational.UniqueConstraint; import org.teiid.designer.metamodels.relational.UniqueKey; import org.teiid.designer.metamodels.relational.View; import org.teiid.designer.metamodels.relational.extension.RelationalModelExtensionAssistant; import org.teiid.designer.metamodels.relational.extension.RelationalModelExtensionConstants; import org.teiid.designer.relational.Messages; import org.teiid.designer.relational.RelationalConstants; import org.teiid.designer.relational.RelationalConstants.DIRECTION; import org.teiid.designer.relational.RelationalConstants.NULLABLE; import org.teiid.designer.relational.RelationalConstants.SEARCHABILITY; import org.teiid.designer.relational.RelationalConstants.TYPES; import org.teiid.designer.relational.RelationalPlugin; import org.teiid.designer.relational.compare.DifferenceReport; import org.teiid.designer.relational.model.DatatypeProcessor; import org.teiid.designer.relational.model.RelationalAccessPattern; import org.teiid.designer.relational.model.RelationalColumn; import org.teiid.designer.relational.model.RelationalForeignKey; import org.teiid.designer.relational.model.RelationalIndex; import org.teiid.designer.relational.model.RelationalParameter; import org.teiid.designer.relational.model.RelationalPrimaryKey; import org.teiid.designer.relational.model.RelationalProcedure; import org.teiid.designer.relational.model.RelationalProcedureResultSet; import org.teiid.designer.relational.model.RelationalReference; import org.teiid.designer.relational.model.RelationalTable; import org.teiid.designer.relational.model.RelationalUniqueConstraint; import org.teiid.designer.relational.model.RelationalView; import org.teiid.designer.relational.model.RelationalViewProcedure; import org.teiid.designer.relational.model.RelationalViewTable; import org.teiid.designer.transformation.model.RelationalViewModelFactory; /** * EmfModelGenerator - creates EMF model objects from RelationalReference counterparts. */ public class EmfModelGenerator { /** * RelationalFactory creates the EMF objects */ public static final RelationalFactory FACTORY = RelationalFactory.eINSTANCE; @SuppressWarnings("javadoc") public static EmfModelGenerator INSTANCE = new EmfModelGenerator(); public static RelationalViewModelFactory VIEW_MODEL_FACTORY = new RelationalViewModelFactory(); private DatatypeProcessor datatypeProcessor = new DatatypeProcessor(); private List<DeferredPair> pkList = new ArrayList<DeferredPair>(); private List<DeferredPair> fkList = new ArrayList<DeferredPair>(); private List<DeferredPair> apList = new ArrayList<DeferredPair>(); private List<DeferredPair> ucList = new ArrayList<DeferredPair>(); private List<RelationalIndex> indexList = new ArrayList<RelationalIndex>(); private List<DeferredPair> deferredProcessingList = new ArrayList<DeferredPair>(); private Map<String, Collection<ModelObjectExtensionAssistant>> classNameToMedAssistantsMap = new HashMap<String,Collection<ModelObjectExtensionAssistant>>(); private Set<String> propsWithNoAssistant = new HashSet<String>(); private Set<String> metaclassesWithNoAssistant = new HashSet<String>(); /** * @return the modelEditor */ private ModelEditor getModelEditor() { return ModelerCore.getModelEditor(); } /** * EMF Model Generator execute * @param diffReport the difference report * @param targetModelResource the model resource * @param progressMonitor progress monitor * @param totalWork the total work units to be done * @return the execution status * @throws ModelerCoreException if problems building model */ public IStatus execute(DifferenceReport diffReport, ModelResource targetModelResource, IProgressMonitor progressMonitor, int totalWork) throws ModelerCoreException { // Clear lists prior to execution clearLists(); int workUnit = totalWork / 5; // Add Relational Extension Assistant if necessary addRelationalExtensionAssistant(targetModelResource); progressMonitor.setTaskName(Messages.emfModelGenerator_generatingModel); // 1) Delete Objects from the target Model progressMonitor.subTask(Messages.emfModelGenerator_deletingPrimaryObjects); List<RelationalReference> objsToDelete = diffReport.getObjectsToDelete().getList(); for( RelationalReference child : objsToDelete ) { // Delete object from targetResource if(child.isChecked()) { deleteMatchingChild(targetModelResource, child); } } progressMonitor.worked(workUnit); // 2) Create Primary Objects in the target Model (Keep Deferred Map) progressMonitor.subTask(Messages.emfModelGenerator_creatingPrimaryObjects); List<RelationalReference> objsToCreate = diffReport.getObjectsToCreate().getList(); for( RelationalReference child : objsToCreate ) { // Create new objects in targetResource if(child.isChecked()) { createObject(child, targetModelResource); } } progressMonitor.worked(workUnit); // 3) Update Objects in the target Model (Keep Deferred Map) progressMonitor.subTask(Messages.emfModelGenerator_updatingPrimaryObjects); List<RelationalReference> objsToUpdate = diffReport.getObjectsToUpdate().getList(); for( RelationalReference child : objsToUpdate ) { if(child.isChecked()) { deleteMatchingChild(targetModelResource, child); createObject(child, targetModelResource); } } progressMonitor.worked(workUnit); // 4) Create the 'Secondary' objects - pks, fks, etc progressMonitor.subTask(Messages.emfModelGenerator_creatingSecondaryObjects); if(!pkList.isEmpty()) { for( DeferredPair item : pkList ) { RelationalPrimaryKey pk = (RelationalPrimaryKey)item.getRelationalReference(); BaseTable table = (BaseTable)item.getEObject(); createPrimaryKey(pk, table, targetModelResource); } } if(!ucList.isEmpty()) { for( DeferredPair item : ucList ) { RelationalUniqueConstraint uc = (RelationalUniqueConstraint)item.getRelationalReference(); BaseTable table = (BaseTable)item.getEObject(); createUniqueConstraint(uc, table, targetModelResource); } } if(!apList.isEmpty()) { for( DeferredPair item : apList ) { RelationalAccessPattern ap = (RelationalAccessPattern)item.getRelationalReference(); Table table = (Table)item.getEObject(); createAccessPattern(ap, table, targetModelResource); } } if(!indexList.isEmpty()) { for( RelationalIndex index : indexList ) { createIndex(index, targetModelResource); } } if(!fkList.isEmpty()) { for( DeferredPair item : fkList ) { RelationalForeignKey fk = (RelationalForeignKey)item.getRelationalReference(); BaseTable table = (BaseTable)item.getEObject(); createForeignKey(fk, table, targetModelResource); } } progressMonitor.worked(workUnit); // 5) Process all 'deferred' operations - Extension properties and descriptions... progressMonitor.subTask(Messages.emfModelGenerator_settingExtensionProps); if(!deferredProcessingList.isEmpty()) { for( DeferredPair item : deferredProcessingList) { RelationalReference relRef = item.getRelationalReference(); EObject eObj = item.getEObject(); processExtensionProperties(targetModelResource,relRef,eObj); setDescription(eObj,relRef.getDescription(),targetModelResource); } } progressMonitor.worked(workUnit); // Build a return status based on errors found MultiStatus multiStatus = new MultiStatus(RelationalPlugin.PLUGIN_ID, IStatus.OK, Messages.emfModelGenerator_modelGenerationSuccess, null); if(!this.propsWithNoAssistant.isEmpty()) { StringBuffer sb = new StringBuffer(); Iterator iter = this.propsWithNoAssistant.iterator(); while(iter.hasNext()) { String prop = (String)iter.next(); sb.append(prop); if(iter.hasNext()) sb.append(","); //$NON-NLS-1$ } multiStatus.add(new Status(IStatus.WARNING, RelationalPlugin.PLUGIN_ID, 0, NLS.bind(Messages.emfModelGenerator_warningAssistantForPropertyNotFound, sb.toString()), null)); } else if(!this.metaclassesWithNoAssistant.isEmpty()) { StringBuffer sb = new StringBuffer(); Iterator iter = this.metaclassesWithNoAssistant.iterator(); while(iter.hasNext()) { String prop = (String)iter.next(); sb.append(prop); if(iter.hasNext()) sb.append(","); //$NON-NLS-1$ } multiStatus.add(new Status(IStatus.WARNING, RelationalPlugin.PLUGIN_ID, 0, NLS.bind(Messages.emfModelGenerator_warningAssistantForMetaclassNotFound, sb.toString()), null)); } // Clear lists on completion clearLists(); return multiStatus; } /** * Clear the lists used during execution */ private void clearLists() { pkList.clear(); fkList.clear(); apList.clear(); ucList.clear(); indexList.clear(); deferredProcessingList.clear(); propsWithNoAssistant.clear(); metaclassesWithNoAssistant.clear(); } /** * Create an EMF object, using the provided RelationalReference object * @param relationalRef the relational model object * @param modelResource the model resource * @return the new EMF object * @throws ModelWorkspaceException if problems building model */ public EObject createObject( RelationalReference relationalRef, ModelResource modelResource) throws ModelWorkspaceException { EObject newEObject = null; switch (relationalRef.getType()) { case TYPES.MODEL: { // NOOP. Shouldn't get here } break; case TYPES.SCHEMA: { // NOOP. Shouldn't get here } break; case TYPES.CATALOG: { // NOOP. Shouldn't get here } break; case TYPES.TABLE: { if( relationalRef instanceof RelationalViewTable ) { // newEObject = VIEW_MODEL_FACTORY.buildObject(relationalRef, modelResource, new NullProgressMonitor()); newEObject = createBaseTable(relationalRef, modelResource); modelResource.getEmfResource().getContents().add(newEObject); VIEW_MODEL_FACTORY.addTransformation((BaseTable)newEObject, (RelationalViewTable)relationalRef); } else { newEObject = createBaseTable(relationalRef, modelResource); modelResource.getEmfResource().getContents().add(newEObject); } } break; case TYPES.VIEW: { newEObject = createView(relationalRef, modelResource); modelResource.getEmfResource().getContents().add(newEObject); } break; case TYPES.PROCEDURE: { if( relationalRef instanceof RelationalViewProcedure ) { newEObject = VIEW_MODEL_FACTORY.buildObject(relationalRef, modelResource, new NullProgressMonitor()); } else { newEObject = createProcedure(relationalRef, modelResource); modelResource.getEmfResource().getContents().add(newEObject); } } break; case TYPES.INDEX: { newEObject = createIndex(relationalRef, modelResource); modelResource.getEmfResource().getContents().add(newEObject); } break; case TYPES.UNDEFINED: default: { RelationalPlugin.Util.log(IStatus.WARNING, NLS.bind(Messages.emfModelGenerator_unknown_object_type_0_cannot_be_processed, relationalRef.getName())); } break; } return newEObject; } /** * Delete the emf object the targetResource that matches the supplied RelationalReference * @param targetResource the target model * @param ref the relational reference * @throws ModelerCoreException */ private void deleteMatchingChild(ModelResource targetResource, RelationalReference ref) throws ModelerCoreException { int refType = ref.getType(); Collection<EObject> existingChildren = targetResource.getEmfResource().getContents(); EObject childToDelete = null; for( EObject child : existingChildren ) { String eObjName = this.getModelEditor().getName(child); if(refType==RelationalConstants.TYPES.TABLE && child instanceof BaseTable) { // BaseTable tableEObj = ((BaseTable)child); // EObject parent = tableEObj.eContainer(); if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } else if(refType==RelationalConstants.TYPES.VIEW && child instanceof View) { if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } else if(refType==RelationalConstants.TYPES.PROCEDURE && child instanceof Procedure) { if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } else if(refType==RelationalConstants.TYPES.INDEX && child instanceof Index) { if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } else if(refType==RelationalConstants.TYPES.SCHEMA && child instanceof Schema) { if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } else if(refType==RelationalConstants.TYPES.CATALOG && child instanceof Catalog) { if(CoreStringUtil.equals(eObjName, ref.getName())) { childToDelete = child; break; } } } if( childToDelete != null ) { this.getModelEditor().delete(childToDelete); } } /** * Create EMF BaseTable from the supplied RelationalReference * @param ref the relational model object * @param modelResource the model resource * @return the new object */ public EObject createBaseTable( final RelationalReference ref, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalTable.class, ref); RelationalTable tableRef = (RelationalTable)ref; // Create and Set Name BaseTable baseTable = FACTORY.createBaseTable(); baseTable.setName(tableRef.getName()); baseTable.setSupportsUpdate(tableRef.getSupportsUpdate()); baseTable.setMaterialized(tableRef.isMaterialized()); baseTable.setNameInSource(tableRef.getNameInSource()); baseTable.setSystem(tableRef.isSystem()); baseTable.setCardinality(tableRef.getCardinality()); // Add Columns for( RelationalColumn column : tableRef.getColumns()) { createColumn(column, baseTable, modelResource); } // Add Primary Keys RelationalPrimaryKey pk = tableRef.getPrimaryKey(); if( pk != null ) { pkList.add(new DeferredPair(pk,baseTable)); } Collection<RelationalUniqueConstraint> ucs = tableRef.getUniqueConstraints(); for(RelationalUniqueConstraint uc: ucs) { ucList.add(new DeferredPair(uc,baseTable)); } for( RelationalAccessPattern ap : tableRef.getAccessPatterns()) { apList.add(new DeferredPair(ap,baseTable)); } for( RelationalForeignKey fk : tableRef.getForeignKeys()) { fkList.add(new DeferredPair(fk,baseTable)); } for( RelationalIndex index : tableRef.getIndexes() ) { indexList.add(index); } // Save objects to Map, so that Extension Properties can be processed later if(!tableRef.getExtensionProperties().isEmpty() || !CoreStringUtil.isEmpty(tableRef.getDescription())) { deferredProcessingList.add(new DeferredPair(tableRef, baseTable)); } return baseTable; } /** * Create EMF View from the supplied RelationalReference * @param ref the relational model object * @param modelResource the model resource * @return the new object */ public EObject createView( final RelationalReference ref, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalView.class, ref); RelationalView viewRef = (RelationalView)ref; // Create and Set Name View view = FACTORY.createView(); view.setName(viewRef.getName()); view.setSupportsUpdate(viewRef.getSupportsUpdate()); view.setMaterialized(viewRef.isMaterialized()); view.setNameInSource(viewRef.getNameInSource()); view.setSystem(viewRef.isSystem()); // Add Columns for( RelationalColumn column : viewRef.getColumns()) { createColumn(column, view, modelResource); } for( RelationalAccessPattern ap : viewRef.getAccessPatterns()) { apList.add(new DeferredPair(ap, view)); } // Add to deferred list, if necessary updateDeferredList(viewRef,view); return view; } /** * Create EMF Column from the supplied RelationalReference * @param ref the relational model object * @param baseTable the table * @param modelResource the model resource * @return the new object */ public EObject createColumn( RelationalReference ref, Table baseTable, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalColumn.class, ref); RelationalColumn columnRef = (RelationalColumn)ref; Column column = FACTORY.createColumn(); column.setOwner(baseTable); column.setName(columnRef.getName()); column.setNameInSource(columnRef.getNameInSource()); column.setAutoIncremented(columnRef.isAutoIncremented()); column.setCaseSensitive(columnRef.isCaseSensitive()); column.setCharacterSetName(columnRef.getCharacterSetName()); column.setCollationName(columnRef.getCollationName()); column.setCurrency(columnRef.isCurrency()); column.setDefaultValue(columnRef.getDefaultValue()); column.setDistinctValueCount(columnRef.getDistinctValueCount()); column.setFixedLength(columnRef.isLengthFixed()); column.setFormat(columnRef.getFormat()); column.setMaximumValue(columnRef.getMaximumValue()); column.setMinimumValue(columnRef.getMinimumValue()); column.setNativeType(columnRef.getNativeType()); column.setNullable(getNullableType(columnRef.getNullable())); column.setNullValueCount(columnRef.getNullValueCount()); column.setPrecision(columnRef.getPrecision()); column.setRadix(columnRef.getRadix()); column.setScale(columnRef.getScale()); column.setSearchability(getSearchabilityType(columnRef.getSearchability())); column.setSelectable(columnRef.isSelectable()); column.setSigned(columnRef.isSigned()); column.setUpdateable(columnRef.isUpdateable()); String dType = columnRef.getDatatype(); if( dType == null || dType.length() == 0) { dType = DatatypeProcessor.DEFAULT_DATATYPE; } EObject datatype = this.datatypeProcessor.findDatatype(dType); if( datatype != null ) { column.setType(datatype); String dTypeName = this.getModelEditor().getName(datatype); int datatypeLength = columnRef.getLength(); if( datatypeLength == 0 && DatatypeProcessor.DEFAULT_DATATYPE.equalsIgnoreCase(dTypeName) ) { columnRef.setLength(DatatypeProcessor.DEFAULT_DATATYPE_LENGTH); } else { columnRef.setLength(datatypeLength); } } column.setLength(columnRef.getLength()); // Add to deferred list, if necessary updateDeferredList(columnRef,column); return column; } /** * Create EMF Column from the supplied RelationalReference * @param ref the relational object * @param procedureResult the procedure result set * @param modelResource the model resource * @return the new object */ public EObject createColumn( RelationalReference ref, ProcedureResult procedureResult, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalColumn.class, ref); RelationalColumn columnRef = (RelationalColumn)ref; Column column = FACTORY.createColumn(); column.setOwner(procedureResult); column.setName(columnRef.getName()); column.setNameInSource(columnRef.getNameInSource()); column.setAutoIncremented(columnRef.isAutoIncremented()); column.setCaseSensitive(columnRef.isCaseSensitive()); column.setCharacterSetName(columnRef.getCharacterSetName()); column.setCollationName(columnRef.getCollationName()); column.setCurrency(columnRef.isCurrency()); column.setDefaultValue(columnRef.getDefaultValue()); column.setDistinctValueCount(columnRef.getDistinctValueCount()); column.setFixedLength(columnRef.isLengthFixed()); column.setFormat(columnRef.getFormat()); column.setLength(columnRef.getLength()); column.setMaximumValue(columnRef.getMaximumValue()); column.setMinimumValue(columnRef.getMinimumValue()); column.setNativeType(columnRef.getNativeType()); String nullableStr = columnRef.getNullable(); column.setNullable(getNullableType(nullableStr)); column.setNullValueCount(columnRef.getNullValueCount()); column.setPrecision(columnRef.getPrecision()); column.setRadix(columnRef.getRadix()); column.setScale(columnRef.getScale()); column.setSearchability(getSearchabilityType(columnRef.getSearchability())); column.setSelectable(columnRef.isSelectable()); column.setSigned(columnRef.isSigned()); column.setUpdateable(columnRef.isUpdateable()); String dType = columnRef.getDatatype(); if( dType == null || dType.length() == 0) { dType = DatatypeProcessor.DEFAULT_DATATYPE; } EObject datatype = this.datatypeProcessor.findDatatype(dType); if( datatype != null ) { column.setType(datatype); String dTypeName = this.getModelEditor().getName(datatype); int datatypeLength = columnRef.getLength(); if( datatypeLength == 0 && DatatypeProcessor.DEFAULT_DATATYPE.equalsIgnoreCase(dTypeName) ) { columnRef.setLength(DatatypeProcessor.DEFAULT_DATATYPE_LENGTH); } else { columnRef.setLength(datatypeLength); } } // Add to deferred list, if necessary updateDeferredList(columnRef,column); return column; } /** * Get the DirectionKind given the string representation * @param dirKindStr the string representation * @return the DirectionKind object equivalent */ private DirectionKind getDirectionKind(String dirKindStr) { if( DIRECTION.IN.equalsIgnoreCase(dirKindStr) ) { return DirectionKind.IN_LITERAL; } if( DIRECTION.IN_OUT.equalsIgnoreCase(dirKindStr) ) { return DirectionKind.INOUT_LITERAL; } if( DIRECTION.OUT.equalsIgnoreCase(dirKindStr) ) { return DirectionKind.OUT_LITERAL; } if( DIRECTION.RETURN.equalsIgnoreCase(dirKindStr) ) { return DirectionKind.RETURN_LITERAL; } return DirectionKind.UNKNOWN_LITERAL; } /** * Get the ProcedureUpdateCount given the string representation * @param updCountStr the string representation * @return the ProcedureUpdateCount object equivalent */ private ProcedureUpdateCount getUpdateCount(String updCountStr) { if( ProcedureUpdateCount.AUTO_LITERAL.getName().equalsIgnoreCase(updCountStr) ) { return ProcedureUpdateCount.AUTO_LITERAL; } if( ProcedureUpdateCount.ONE_LITERAL.getName().equalsIgnoreCase(updCountStr) ) { return ProcedureUpdateCount.ONE_LITERAL; } if( ProcedureUpdateCount.MULTIPLE_LITERAL.getName().equalsIgnoreCase(updCountStr) ) { return ProcedureUpdateCount.MULTIPLE_LITERAL; } if( ProcedureUpdateCount.ZERO_LITERAL.getName().equalsIgnoreCase(updCountStr) ) { return ProcedureUpdateCount.ZERO_LITERAL; } return ProcedureUpdateCount.AUTO_LITERAL; } /** * Get the MultiplicityKind given the string representation * @param multKindStr the string representation * @return the MultiplicityKind object equivalent */ private MultiplicityKind getMultiplictyKind(String multKindStr) { if( MultiplicityKind.MANY_LITERAL.getName().equalsIgnoreCase(multKindStr) ) { return MultiplicityKind.MANY_LITERAL; } if( MultiplicityKind.ONE_LITERAL.getName().equalsIgnoreCase(multKindStr) ) { return MultiplicityKind.ONE_LITERAL; } if( MultiplicityKind.ZERO_TO_ONE_LITERAL.getName().equalsIgnoreCase(multKindStr) ) { return MultiplicityKind.ZERO_TO_ONE_LITERAL; } if( MultiplicityKind.ZERO_TO_MANY_LITERAL.getName().equalsIgnoreCase(multKindStr) ) { return MultiplicityKind.ZERO_TO_MANY_LITERAL; } return MultiplicityKind.UNSPECIFIED_LITERAL; } /** * Get the NullableType given the string representation * @param nullableStr the string representation * @return the NullableType object equivalent */ private NullableType getNullableType(String nullableStr) { if( NULLABLE.NULLABLE.equalsIgnoreCase(nullableStr) ) { return NullableType.NULLABLE_LITERAL; } if( NULLABLE.NO_NULLS.equalsIgnoreCase(nullableStr) ) { return NullableType.NO_NULLS_LITERAL; } return NullableType.NULLABLE_UNKNOWN_LITERAL; } /** * Get the SearchabilityType given the string representation * @param searchableStr the string representation * @return the SearchabilityType object equivalent */ private SearchabilityType getSearchabilityType(String searchableStr) { if( SEARCHABILITY.UNSEARCHABLE.equalsIgnoreCase(searchableStr) ) { return SearchabilityType.UNSEARCHABLE_LITERAL; } if( SEARCHABILITY.ALL_EXCEPT_LIKE.equalsIgnoreCase(searchableStr) ) { return SearchabilityType.ALL_EXCEPT_LIKE_LITERAL; } if( SEARCHABILITY.LIKE_ONLY.equalsIgnoreCase(searchableStr) ) { return SearchabilityType.LIKE_ONLY_LITERAL; } return SearchabilityType.SEARCHABLE_LITERAL; } /** * Create EMF Index from the supplied RelationalReference * @param ref the relational index object * @param modelResource the model resource * @return the index object */ public EObject createIndex( RelationalReference ref, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalIndex.class, ref); RelationalIndex indexRef = (RelationalIndex)ref; Index index = FACTORY.createIndex(); index.setName(indexRef.getName()); index.setNameInSource(index.getNameInSource()); index.setFilterCondition(indexRef.getFilterCondition()); index.setAutoUpdate(indexRef.isAutoUpdate()); index.setNullable(indexRef.isNullable()); index.setUnique(indexRef.isUnique()); // Add the columns in the correct order final List indexColumns = index.getColumns(); for (RelationalColumn relColumn : indexRef.getColumns() ) { BaseTable baseTable = getTable(relColumn.getParent().getName(), modelResource); Column column = getColumn(relColumn.getName(), baseTable); if( column != null ) { indexColumns.add(column); } } // Add to deferred list, if necessary updateDeferredList(indexRef,index); return index; } /** * Create EMF PrimaryKey from the supplied RelationalReference * @param ref the relational pk object * @param modelResource the model resource * @return the primary key object */ private EObject createPrimaryKey( RelationalReference ref, BaseTable baseTable, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalPrimaryKey.class, ref); RelationalPrimaryKey pkRef = (RelationalPrimaryKey)ref; // Create the primary key final PrimaryKey primaryKey = FACTORY.createPrimaryKey(); // Set the reference to the table .. primaryKey.setTable(baseTable); primaryKey.setName(pkRef.getName()); primaryKey.setNameInSource(pkRef.getNameInSource()); // Add the columns in the correct order final List keyColumns = primaryKey.getColumns(); for (RelationalColumn relColumn : pkRef.getColumns() ) { Column column = getColumn(relColumn.getName(), baseTable); if( column != null ) { keyColumns.add(column); } } // Add to deferred list, if necessary updateDeferredList(pkRef,primaryKey); return primaryKey; } /** * Create EMF ForeignKey from the supplied RelationalReference * @param ref the relational fk object * @param baseTable the table parent of the fk * @param modelResource the model resource * @return the foreign key object */ public EObject createForeignKey( RelationalReference ref, BaseTable baseTable, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalForeignKey.class, ref); RelationalForeignKey fkRef = (RelationalForeignKey)ref; // Create the primary key final ForeignKey foreignKey = FACTORY.createForeignKey(); // Set the reference to the table .. foreignKey.setTable(baseTable); foreignKey.setName(fkRef.getName()); foreignKey.setNameInSource(fkRef.getNameInSource()); foreignKey.setForeignKeyMultiplicity(getMultiplictyKind(fkRef.getForeignKeyMultiplicity())); foreignKey.setPrimaryKeyMultiplicity(getMultiplictyKind(fkRef.getPrimaryKeyMultiplicity())); // Add the columns in the correct order final List keyColumns = foreignKey.getColumns(); for (RelationalColumn relColumn : fkRef.getColumns() ) { Column column = getColumn(relColumn.getName(), baseTable); if( column != null ) { keyColumns.add(column); } } BaseTable fkTable = getTable(fkRef.getUniqueKeyTableName(), modelResource); String ukRefName = fkRef.getUniqueKeyName(); if( fkTable != null && ukRefName != null ) { if( fkTable.getPrimaryKey() != null && fkTable.getPrimaryKey().getName().equalsIgnoreCase(ukRefName)) { foreignKey.setUniqueKey(fkTable.getPrimaryKey()); } else if( ! fkTable.getUniqueConstraints().isEmpty() ) { for( Object key : fkTable.getUniqueConstraints()) { String keyName = this.getModelEditor().getName((UniqueKey)key); if( keyName.equalsIgnoreCase(ukRefName) ) { foreignKey.setUniqueKey((UniqueKey)key); } } } } // Add to deferred list, if necessary updateDeferredList(fkRef,foreignKey); return foreignKey; } /** * Create EMF AccessPattern from the supplied RelationalReference * @param ref the relational AccessPattern object * @param baseTable the table parent of the ap * @param modelResource the model resource * @return the AccessPattern object */ private EObject createAccessPattern( RelationalReference ref, Table baseTable, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalAccessPattern.class, ref); RelationalAccessPattern apRef = (RelationalAccessPattern)ref; // Create the primary key final AccessPattern accessPattern = FACTORY.createAccessPattern(); // Set the reference to the table .. accessPattern.setTable(baseTable); accessPattern.setName(apRef.getName()); accessPattern.setNameInSource(apRef.getNameInSource()); // Add the columns in the correct order final List keyColumns = accessPattern.getColumns(); for (RelationalColumn relColumn : apRef.getColumns() ) { Column column = getColumn(relColumn.getName(), baseTable); if( column != null ) { keyColumns.add(column); } } // Add to deferred list, if necessary updateDeferredList(apRef,accessPattern); return accessPattern; } /** * Create EMF UniqueConstraint from the supplied RelationalReference * @param ref the relational UniqueConstraint object * @param baseTable the table parent of the uc * @param modelResource the model resource * @return the UniqueConstraint object */ private EObject createUniqueConstraint( RelationalReference ref, BaseTable baseTable, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalUniqueConstraint.class, ref); RelationalUniqueConstraint ucRef = (RelationalUniqueConstraint)ref; // Create the primary key final UniqueConstraint uniqueConstraint = FACTORY.createUniqueConstraint(); // Set the reference to the table .. uniqueConstraint.setTable(baseTable); uniqueConstraint.setName(ucRef.getName()); uniqueConstraint.setNameInSource(ucRef.getNameInSource()); // Add the columns in the correct order final List keyColumns = uniqueConstraint.getColumns(); for (RelationalColumn relColumn : ucRef.getColumns() ) { Column column = getColumn(relColumn.getName(), baseTable); if( column != null ) { keyColumns.add(column); } } // Add to deferred list, if necessary updateDeferredList(ucRef,uniqueConstraint); return uniqueConstraint; } /** * * @param name * @param baseTable * @return */ private Column getColumn(String name, Table baseTable) { for( Object column : baseTable.getColumns()) { if( column instanceof Column && ((Column)column).getName().equalsIgnoreCase(name) ) { return (Column)column; } } return null; } /** * * @param tableName * @param modelResource * @return */ private BaseTable getTable(String tableName, ModelResource modelResource) { try { for (EObject eObj : modelResource.getEmfResource().getContents() ) { String eObjName = this.getModelEditor().getName(eObj); if( eObj instanceof BaseTable && eObjName != null && eObjName.equalsIgnoreCase(tableName)) { return (BaseTable)eObj; } } } catch (ModelWorkspaceException e) { RelationalPlugin.Util.log(IStatus.ERROR, NLS.bind(Messages.emfModelGenerator_error_finding_table_named, tableName)); } return null; } /** * Create EMF Procedure from the supplied RelationalReference * @param ref the relational Procedure object * @param modelResource the model resource * @return the Procedure object */ public EObject createProcedure( final RelationalReference ref, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalProcedure.class, ref); RelationalProcedure procedureRef = (RelationalProcedure)ref; // Create and Set Name Procedure procedure = FACTORY.createProcedure(); procedure.setName(procedureRef.getName()); procedure.setNameInSource(procedureRef.getNameInSource()); procedure.setFunction(procedureRef.isFunction()); procedure.setUpdateCount(getUpdateCount(procedureRef.getUpdateCount())); // Add Columns for( RelationalParameter paramRef : procedureRef.getParameters()) { createParameter(paramRef, procedure, modelResource); } if( procedureRef.getResultSet() != null ) { createResultSet(procedureRef.getResultSet(), procedure, modelResource); } // Add to deferred list, if necessary updateDeferredList(procedureRef,procedure); return procedure; } /** * Create EMF ProcedureParameter from the supplied RelationalReference * @param ref the parameter object * @param procedure the parent procedure * @param modelResource the model resource * @return the ProcedureParameter EObject */ public EObject createParameter( RelationalReference ref, Procedure procedure, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalParameter.class, ref); RelationalParameter parameterRef = (RelationalParameter)ref; ProcedureParameter parameter = FACTORY.createProcedureParameter(); parameter.setProcedure(procedure); parameter.setName(parameterRef.getName()); parameter.setNameInSource(parameterRef.getNameInSource()); parameter.setDefaultValue(parameterRef.getDefaultValue()); parameter.setDirection(getDirectionKind(parameterRef.getDirection())); parameter.setNativeType(parameterRef.getNativeType()); parameter.setNullable(getNullableType(parameterRef.getNullable())); parameter.setPrecision(parameterRef.getPrecision()); parameter.setRadix(parameterRef.getRadix()); parameter.setScale(parameterRef.getScale()); String dType = parameterRef.getDatatype(); if( dType == null || dType.length() == 0) { dType = DatatypeProcessor.DEFAULT_DATATYPE; } EObject datatype = this.datatypeProcessor.findDatatype(dType); if( datatype != null ) { parameter.setType(datatype); String dTypeName = this.getModelEditor().getName(datatype); int datatypeLength = parameterRef.getLength(); if( datatypeLength == 0 && DatatypeProcessor.DEFAULT_DATATYPE.equalsIgnoreCase(dTypeName) ) { parameter.setLength(DatatypeProcessor.DEFAULT_DATATYPE_LENGTH); } else { parameter.setLength(datatypeLength); } } // Add to deferred list, if necessary updateDeferredList(parameterRef,parameter); return parameter; } /** * Create EMF ProcedureResult from the supplied RelationalReference * @param ref the result set object * @param procedure the parent procedure * @param modelResource the model resource * @return the ProcedureResult object */ public EObject createResultSet( RelationalReference ref, Procedure procedure, ModelResource modelResource) { CoreArgCheck.isInstanceOf(RelationalProcedureResultSet.class, ref); RelationalProcedureResultSet resultSetRef = (RelationalProcedureResultSet)ref; ProcedureResult result = FACTORY.createProcedureResult(); result.setProcedure(procedure); result.setName(resultSetRef.getName()); result.setNameInSource(resultSetRef.getNameInSource()); // Add Columns for( RelationalColumn colRef : resultSetRef.getColumns()) { createColumn(colRef, result, modelResource); } // Add to deferred list, if necessary updateDeferredList(resultSetRef,result); return result; } /** * Adds the RelationalReference - EObject pair to the deferred processing list, if there are * extension properties or a description to add. Also RelationalProcedure are deferred to process extensions * @param relRef the RelationalReference * @param eObj the EObject */ private void updateDeferredList(RelationalReference relRef, EObject eObj) { if(!relRef.getExtensionProperties().isEmpty() || !CoreStringUtil.isEmpty(relRef.getDescription()) || relRef instanceof RelationalProcedure) { deferredProcessingList.add(new DeferredPair(relRef, eObj)); } } /** * Set the description on the EMF object. Looks up annotation - if not found then the annotation is created. * @param eObject the target object * @param description the description * @param modelResource the model resource */ public void setDescription( EObject eObject, String description, ModelResource modelResource ) { if (description != null && description.trim().length() > 0) { try { AnnotationContainer annotations = null; final Iterator contents = modelResource.getEmfResource().getContents().iterator(); while (contents.hasNext()) { final Object next = contents.next(); if (next instanceof AnnotationContainer) { annotations = (AnnotationContainer)next; break; } } // while if (annotations == null) { annotations = CoreFactory.eINSTANCE.createAnnotationContainer(); modelResource.getEmfResource().getContents().add(annotations); } Annotation annotation = annotations.findAnnotation(eObject); if (annotation == null) { annotation = CoreFactory.eINSTANCE.createAnnotation(); annotations.getAnnotations().add(annotation); annotation.setAnnotatedObject(eObject); } annotation.setDescription(description); } catch (ModelWorkspaceException e) { RelationalPlugin.Util.log(IStatus.ERROR, NLS.bind(Messages.emfModelGenerator_error_adding_desciption_to_0, eObject)); } } } /** * Process the extension properties for a relational entity. This will apply the necessary med to the model (if needed) and add the * appropriate extension properties to the model. * @param modelResource the ModelResource * @param relationalEntity the RelationalReference * @param eObject the EObject * */ private void processExtensionProperties(ModelResource modelResource, RelationalReference relationalEntity, EObject eObject) { // RelationalProcedure has fields which are transferred to extension properties if(relationalEntity.getType()==TYPES.PROCEDURE) { processProcedureExtensionProperties(modelResource,(RelationalProcedure)relationalEntity,eObject); } Properties extensionProperties = relationalEntity.getExtensionProperties(); Iterator<Object> keyIter = extensionProperties.keySet().iterator(); while(keyIter.hasNext()) { String propName = (String)keyIter.next(); String propValue = extensionProperties.getProperty(propName); // Find an extension assistant that can create this extension property (if it exists) ModelObjectExtensionAssistant assistant = getModelExtensionAssistant(eObject.getClass().getName(),propName); if(assistant!=null) { // Ensure that the Model supports the MED applyMedIfNecessary(modelResource,assistant); // Set the property value via the assistant setPropertyValue(assistant,eObject,propName,propValue); } } } /** * Process the RelationalProcedure, converting values to EMF extension properties * @param modelResource the ModelResource * @param relationalProcedure the RelationalProcedure * @param eObject the EObject * */ private void processProcedureExtensionProperties(ModelResource modelResource, RelationalProcedure relationalProcedure, EObject eObject) { RelationalModelExtensionAssistant relationalExtensionAssistant = getRelationalExtensionAssistant(); String nativeQuery = relationalProcedure.getNativeQuery(); if(!CoreStringUtil.isEmpty(nativeQuery)) { setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.NATIVE_QUERY,nativeQuery); } boolean isNonPrepared = relationalProcedure.isNonPrepared(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.NON_PREPARED,String.valueOf(isNonPrepared)); // Functions have many additional extension properties boolean isFunction = relationalProcedure.isFunction(); if(isFunction) { String functionCategory = relationalProcedure.getFunctionCategory(); if(!CoreStringUtil.isEmpty(functionCategory)) { setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.FUNCTION_CATEGORY,functionCategory); } String javaClass = relationalProcedure.getJavaClassName(); if(!CoreStringUtil.isEmpty(javaClass)) { setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.JAVA_CLASS,javaClass); } String javaMethod = relationalProcedure.getJavaMethodName(); if(!CoreStringUtil.isEmpty(javaMethod)) { setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.JAVA_METHOD,javaMethod); } boolean isVariableArgs = relationalProcedure.isVariableArguments(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.VARARGS,String.valueOf(isVariableArgs)); boolean isNullOnNull = relationalProcedure.isReturnsNullOnNull(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.NULL_ON_NULL,String.valueOf(isNullOnNull)); boolean isDeterministic = relationalProcedure.isDeterministic(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.DETERMINISTIC,String.valueOf(isDeterministic)); // Additional Properties for Aggregate 'true' boolean isAggregate = relationalProcedure.isAggregate(); if(isAggregate) { setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.AGGREGATE,String.valueOf(isAggregate)); boolean isAnalytic = relationalProcedure.isAnalytic(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.ANALYTIC,String.valueOf(isAnalytic)); boolean isAllowsOrderBy = relationalProcedure.isAllowsOrderBy(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.ALLOWS_ORDER_BY,String.valueOf(isAllowsOrderBy)); boolean isUseDistinctRows = relationalProcedure.isUseDistinctRows(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.USES_DISTINCT_ROWS,String.valueOf(isUseDistinctRows)); boolean isAllowsDistinct = relationalProcedure.isAllowsDistinct(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.ALLOWS_DISTINCT,String.valueOf(isAllowsDistinct)); boolean isDecomposable = relationalProcedure.isDecomposable(); setPropertyValue(relationalExtensionAssistant,eObject,RelationalConstants.PROCEDURE_EXT_PROPERTIES.DECOMPOSABLE,String.valueOf(isDecomposable)); } } } /** * Set a property value via the supplied assistant. the propId should NOT be namespaced * @param assistant the ModelObjectExtensionAssistant * @param eObject the EObject * @param propId the property name * @param propValue the property value * */ private void setPropertyValue(ModelObjectExtensionAssistant assistant, EObject eObject, String propId, String propValue) { // Check if the propId is already namespaced, otherwise prepend the assistant's namespace prefix String namespacedId = null; if(propId.indexOf(':') != -1) { namespacedId = propId; } else { namespacedId = assistant.getNamespacePrefix()+':'+propId; } try { if( assistant.supportsProperty(eObject, propId) ) { assistant.setPropertyValue(eObject, namespacedId, propValue); } } catch (Exception ex) { RelationalPlugin.Util.log(IStatus.ERROR,ex, NLS.bind(Messages.emfModelGenerator_errorSettingPropertyValue, namespacedId)); } } /** * If the ModelResource does not support the assistants namespace, apply its MED to the model * @param modelResource the model resource * @param assistant the ModelObjectExtensionAssistant * @throws Exception exception if there's a problem applying the MED */ private void applyMedIfNecessary(final ModelResource modelResource, ModelObjectExtensionAssistant assistant) { if (modelResource != null && !modelResource.isReadOnly()) { try{ if(!assistant.supportsMyNamespace(modelResource)) { assistant.saveModelExtensionDefinition(modelResource); } } catch (Exception e) { RelationalPlugin.Util.log(IStatus.ERROR, Messages.emfModelGenerator_errorApplyingMedToModel); } } } /** * Get the ModelExtensionAssistant that can handle the supplied property for the specified metaClass. Currently, this will * get the first valid assistant found (if more than one can handle the property) * @param eObjectClassName the metaclass name * @param propId the property * @return the assistant * */ private ModelObjectExtensionAssistant getModelExtensionAssistant( String eObjectClassName, String propId ) { // Get available assistants for the provided className. If the map has no entry, go to the ExtensionPlugin and populate it first. Collection<ModelObjectExtensionAssistant> assistants = null; if(this.classNameToMedAssistantsMap.containsKey(eObjectClassName)) { assistants = this.classNameToMedAssistantsMap.get(eObjectClassName); } else { Collection<ModelExtensionAssistant> medAssistants = ExtensionPlugin.getInstance().getRegistry().getModelExtensionAssistants(eObjectClassName); assistants = new ArrayList<ModelObjectExtensionAssistant>(); for(ModelExtensionAssistant medAssistant: medAssistants) { if(medAssistant instanceof ModelObjectExtensionAssistant) { assistants.add((ModelObjectExtensionAssistant)medAssistant); } } this.classNameToMedAssistantsMap.put(eObjectClassName, assistants); } // no assistants found that have properties defined for the model object type if (assistants.isEmpty()) { String metaclassShortName = getMetaclassShortName(eObjectClassName); metaclassesWithNoAssistant.add(metaclassShortName); return null; } // If property is namespaced, get the assistant with matching namespace if(isNamespaced(propId)) { ModelObjectExtensionAssistant matchingAssistant = getAssistantWithNamespace(getExtensionPropertyNamespace(propId),assistants); if(matchingAssistant!=null) return matchingAssistant; } else { // find the assistant for the property for (ModelExtensionAssistant assistant : assistants) { // Prepend the assistant namespace to the propertyId, since it doesnt have one String namespacedId = assistant.getNamespacePrefix()+':'+propId; if(hasMatchingPropertyName(assistant.getModelExtensionDefinition(), eObjectClassName, namespacedId)) { return ((assistant instanceof ModelObjectExtensionAssistant) ? (ModelObjectExtensionAssistant)assistant : null); } } } this.propsWithNoAssistant.add(propId); return null; } /** * Get the ModelExtensionAssistant matching the supplied namespace * @param namespace the namespace * @param assistants the list of assistants * @return the assistant which matches the supplied namespace * */ private ModelObjectExtensionAssistant getAssistantWithNamespace( String namespace, Collection<ModelObjectExtensionAssistant> assistants ) { ModelObjectExtensionAssistant result = null; for(ModelObjectExtensionAssistant assistant: assistants) { if(assistant.getNamespacePrefix().equalsIgnoreCase(namespace)) { result = assistant; break; } } return result; } /** * Get the Namespace from the extension property name. The propertyName may or may not be namespaced. * If it's not a null is returned * @param propName the extension property name, including namespace * @return the namespace, if present. 'null' if not namespaced */ private String getExtensionPropertyNamespace(String propName) { String namespace = null; if(!CoreStringUtil.isEmpty(propName)) { int index = propName.indexOf(':'); if(index!=-1) { namespace = propName.substring(0,index); } } return namespace; } /** * Determine if the property name has a leading namespace * @param propName the extension property name, including namespace * @return 'true' if a namespace is present, 'false' if not. */ private boolean isNamespaced(String propName) { boolean isNamespaced = false; if(!CoreStringUtil.isEmpty(propName)) { isNamespaced = propName.indexOf(':') != -1; } return isNamespaced; } private String getMetaclassShortName(String metaclass) { return AbstractMetaclassNameProvider.getLabel(metaclass); } /** * Determine if the ModelExtensionDefinition has a propertyId that matches the supplied property * @param med the ModelExtensionDefinition * @param metaclassName the extended metaclass name * @param propId the property id * @return 'true' if the med has a matching propertyDefn, 'false' if not */ private boolean hasMatchingPropertyName(ModelExtensionDefinition med, String metaclassName, String propId) { ModelExtensionPropertyDefinition propDefn = med.getPropertyDefinition(metaclassName, propId); return propDefn!=null ? true : false; } /** * Add the RelationalExtension to the supplied ModelResource, if it has not already been added. * @param modelResource */ private void addRelationalExtensionAssistant(ModelResource modelResource) { final RelationalModelExtensionAssistant assistant = getRelationalExtensionAssistant(); try { assistant.applyMedIfNecessary(modelResource.getUnderlyingResource()); } catch (Exception e) { RelationalPlugin.Util.log(IStatus.ERROR, e, e.getMessage()); } } /** * Get the RelationalModelExtensionAssistant from the MED registry * @param modelResource */ private RelationalModelExtensionAssistant getRelationalExtensionAssistant() { final ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry(); final String prefix = RelationalModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix(); final RelationalModelExtensionAssistant assistant = (RelationalModelExtensionAssistant)registry.getModelExtensionAssistant(prefix); return assistant; } /** * Object for retaining the object pairs for deferred processing */ class DeferredPair { private RelationalReference relationalRef; private EObject eObj; public DeferredPair(RelationalReference relRef, EObject eObj) { this.relationalRef=relRef; this.eObj=eObj; } RelationalReference getRelationalReference() { return this.relationalRef; } EObject getEObject() { return this.eObj; } } }