/*
* 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.relational.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.osgi.util.NLS;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelUtil;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.core.workspace.ModelWorkspaceManager;
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.core.ModelType;
import org.teiid.designer.metamodels.relational.AccessPattern;
import org.teiid.designer.metamodels.relational.BaseTable;
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.RelationalPackage;
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.RelationalPlugin;
/**
* Class provides building EMF Relational Metamodel objects from Relational Model objects
*
* @since 8.0
*/
public class RelationalModelFactory implements RelationalConstants {
/**
*
*/
public static final String RELATIONAL_PACKAGE_URI = RelationalPackage.eNS_URI;
/**
*
*/
public static final RelationalFactory FACTORY = RelationalFactory.eINSTANCE;
/**
*
*/
public static RelationalModelFactory INSTANCE = new RelationalModelFactory();
private DatatypeProcessor datatypeProcessor;
private Map<RelationalForeignKey, BaseTable> fkTableMap = new HashMap<RelationalForeignKey, BaseTable>();
private Collection<RelationalIndex> indexes = new ArrayList<RelationalIndex>();
// Map<base table, reference table>
private Map<Table, RelationalTable> matTableRefMap = new HashMap<Table, RelationalTable>();
private Map<String, Collection<ModelObjectExtensionAssistant>> classNameToMedAssistantsMap = new HashMap<String,Collection<ModelObjectExtensionAssistant>>();
private boolean allowsZeroStringLength;
/**
*
*/
public RelationalModelFactory() {
super();
this.datatypeProcessor = new DatatypeProcessor();
allowsZeroStringLength = false;
}
protected RelationalModelExtensionAssistant getExtensionAssistant() {
final ModelExtensionRegistry registry = ExtensionPlugin.getInstance().getRegistry();
final String prefix = RelationalModelExtensionConstants.NAMESPACE_PROVIDER.getNamespacePrefix();
final RelationalModelExtensionAssistant assistant = (RelationalModelExtensionAssistant)registry.getModelExtensionAssistant(prefix);
return assistant;
}
/**
* Creates a relational model given a <code>IPath</code> location and a model name
*
* @param location the container location of the model
* @param modelName the model name
* @return the ModelResource
* @throws ModelWorkspaceException if error creating model
*/
public ModelResource createRelationalModel( IPath location, String modelName) throws ModelWorkspaceException {
final ModelResource resrc = ModelerCore.createModelResource(location, modelName);
resrc.getModelAnnotation().setPrimaryMetamodelUri( RELATIONAL_PACKAGE_URI );
resrc.getModelAnnotation().setModelType(ModelType.PHYSICAL_LITERAL);
ModelerCore.getModelEditor().getAllContainers(resrc.getEmfResource());
return resrc;
}
/**
* Creates a relational model given a <code>IContainer</code> location (Project or Folder) and a model name
*
* @param container the resource container
* @param modelName the model name
* @return the model resource
* @throws ModelWorkspaceException if problems creating model
*/
public ModelResource createRelationalModel( IContainer container, String modelName) throws ModelWorkspaceException {
IProject project = container.getProject();
String actualModelName = modelName;
if( !modelName.toLowerCase().endsWith(XMI_EXT)) {
actualModelName = modelName + XMI_EXT;
}
IPath relativeModelPath = container.getFullPath().removeFirstSegments(1).append(actualModelName);
final IFile modelFile = project.getFile( relativeModelPath );
final ModelResource resrc = ModelerCore.create( modelFile );
resrc.getModelAnnotation().setPrimaryMetamodelUri( RELATIONAL_PACKAGE_URI );
resrc.getModelAnnotation().setModelType(ModelType.PHYSICAL_LITERAL);
ModelerCore.getModelEditor().getAllContainers(resrc.getEmfResource());
return resrc;
}
/**
* @param modelResource the model resource
* @param model the relational model structure
* @param progressMonitor progress monitor
*/
public void build(ModelResource modelResource, RelationalModel model, IProgressMonitor progressMonitor) {
try {
RelationalModelFactory builder = new RelationalModelFactory();
final RelationalModelExtensionAssistant assistant = getExtensionAssistant();
try {
assistant.applyMedIfNecessary(modelResource.getUnderlyingResource());
} catch (Exception e) {
RelationalPlugin.Util.log(IStatus.ERROR, e, e.getMessage());
}
builder.buildFullModel(model, modelResource, progressMonitor);
modelResource.save(new NullProgressMonitor(), true);
} catch (ModelerCoreException e) {
RelationalPlugin.Util.log(IStatus.ERROR, e, e.getMessage());
} catch (CoreException e) {
// TODO Auto-generated catch block
RelationalPlugin.Util.log(IStatus.ERROR, e, e.getMessage());
}
}
/**
* @param model the relational model structure
* @param modelResource the model resource
* @param progressMonitor progress monitor
* @throws CoreException
*/
public void buildFullModel(RelationalModel model, ModelResource modelResource, IProgressMonitor progressMonitor) throws CoreException {
progressMonitor.setTaskName(Messages.relationalModelFactory_creatingModelChildren);
for( RelationalReference child : model.getChildren() ) {
int processType = child.getProcessType();
switch(processType) {
case RelationalReference.IGNORE : {
// Do nothing
} break;
case RelationalReference.CREATE_ANYWAY : {
buildObject(child, modelResource, progressMonitor);
} break;
case RelationalReference.CREATE_UNIQUE_NAME : {
// Currently NOT implemented
} break;
case RelationalReference.REPLACE : {
deleteChildWithName(modelResource, child, progressMonitor);
buildObject(child, modelResource, progressMonitor);
} break;
}
progressMonitor.worked(1);
}
progressMonitor.setTaskName(Messages.relationalModelFactory_creatingForeigneKeys);
progressMonitor.worked(1);
for( RelationalForeignKey fkRef : fkTableMap.keySet()) {
createForeignKey(fkRef, fkTableMap.get(fkRef), modelResource);
}
progressMonitor.setTaskName(Messages.relationalModelFactory_creatingIndexes);
progressMonitor.worked(1);
for( RelationalIndex indexRef : indexes ) {
createIndex(indexRef, modelResource);
}
progressMonitor.setTaskName(Messages.relationalModelFactory_settingMaterializedReferences);
progressMonitor.worked(1);
for( Table table : matTableRefMap.keySet() ) {
setMatTableReference(table, (RelationalTable)matTableRefMap.get(table), modelResource);
}
}
private void deleteChildWithName(ModelResource targetResource, RelationalReference ref, IProgressMonitor progressMonitor) throws ModelerCoreException {
progressMonitor.setTaskName(NLS.bind(Messages.relationalModelFactory_replacingModelObject, ref.getName()));
Collection<EObject> existingChildren = targetResource.getEmfResource().getContents();
EObject childToDelete = null;
for( EObject child : existingChildren ) {
String name = ModelerCore.getModelEditor().getName(child);
if( name != null && name.equalsIgnoreCase(ref.getName()) ) {
childToDelete = child;
break;
}
}
if( childToDelete != null ) {
ModelerCore.getModelEditor().delete(childToDelete);
}
}
/**
* @param relationalRef the relational model object
* @param modelResource the model resource
* @param progressMonitor progress monitor
* @return the new model object
* @throws ModelWorkspaceException if problems building model
*/
public EObject buildObject( RelationalReference relationalRef, ModelResource modelResource, IProgressMonitor progressMonitor) throws ModelWorkspaceException {
EObject newEObject = null;
progressMonitor.setTaskName(NLS.bind(Messages.relationalModelFactory_creatingModelChild, relationalRef.getName()));
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: {
newEObject = createBaseTable(relationalRef, modelResource);
// In the case of the new object wizards, users can create Indexes while creating a table
// So just walk these and add them to the model too
for( RelationalIndex index : ((RelationalTable)relationalRef).getIndexes() ) {
EObject newIndex = createIndex(index, modelResource);
}
} break;
case TYPES.VIEW: {
newEObject = createView(relationalRef, modelResource);
} break;
case TYPES.PROCEDURE: {
newEObject = createProcedure(relationalRef, modelResource);
} break;
case TYPES.INDEX: {
indexes.add((RelationalIndex)relationalRef);
} break;
case TYPES.UNDEFINED:
default: {
RelationalPlugin.Util.log(IStatus.WARNING,
NLS.bind(Messages.relationalModelFactory_unknown_object_type_0_cannot_be_processed, relationalRef.getName()));
} break;
}
// // Apply Extension Properties
// processExtensionProperties(modelResource,relationalRef,newEObject);
return newEObject;
}
/**
* @param ref the relational model object
* @param modelResource the model resource
* @return the new object
*/
public EObject createBaseTable( final RelationalReference ref, ModelResource modelResource) throws ModelWorkspaceException {
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());
modelResource.getEmfResource().getContents().add(baseTable);
// Set Description
if( tableRef.getDescription() != null ) {
createAnnotation(baseTable, tableRef.getDescription(), modelResource);
}
// Add Columns
for( RelationalColumn column : tableRef.getColumns()) {
createColumn(column, baseTable, modelResource);
}
// Add Primary Keys
// Add Columns
RelationalPrimaryKey pk = tableRef.getPrimaryKey();
if( pk != null ) {
createPrimaryKey(pk, baseTable, modelResource);
}
Collection<RelationalUniqueConstraint> uniqueConstraints = tableRef.getUniqueConstraints();
if( uniqueConstraints != null) {
for (RelationalUniqueConstraint uc : uniqueConstraints) {
createUniqueConstraint(uc, baseTable, modelResource);
}
}
for( RelationalAccessPattern ap : tableRef.getAccessPatterns()) {
createAccessPattern(ap, baseTable, modelResource);
}
for( RelationalForeignKey fk : tableRef.getForeignKeys()) {
fkTableMap.put(fk, baseTable);
}
if( tableRef.isMaterialized() && tableRef.getMaterializedTable() != null ) {
matTableRefMap.put(baseTable, (RelationalTable)tableRef);
}
// Apply Extension Properties
processExtensionProperties(modelResource,tableRef,baseTable);
return baseTable;
}
/**
* @param ref the relational model object
* @param modelResource the model resource
* @return the new object
*/
public EObject createView( final RelationalReference ref, ModelResource modelResource) throws ModelWorkspaceException {
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());
modelResource.getEmfResource().getContents().add(view);
// Set Description
if( viewRef.getDescription() != null ) {
createAnnotation(view, viewRef.getDescription(), modelResource);
}
// Add Columns
for( RelationalColumn column : viewRef.getColumns()) {
createColumn(column, view, modelResource);
}
for( RelationalAccessPattern uc : viewRef.getAccessPatterns()) {
createAccessPattern(uc, view, modelResource);
}
if( viewRef.isMaterialized() && viewRef.getMaterializedTable() != null ) {
matTableRefMap.put(view, (RelationalTable)viewRef);
}
// Apply Extension Properties
processExtensionProperties(modelResource,viewRef,view);
return view;
}
/**
* @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.setLength(columnRef.getLength());
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());
EObject datatype = this.datatypeProcessor.findDatatype(columnRef.getDatatype());
// columnRef.getDatatype(),
// columnRef.getLength(),
// columnRef.getPrecision(),
// columnRef.getScale(),
// new ArrayList());
if( datatype != null ) {
column.setType(datatype);
}
// Set Description
if( columnRef.getDescription() != null ) {
createAnnotation(column, columnRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,columnRef,column);
return column;
}
/**
* @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());
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 = ModelerCore.getModelEditor().getName(datatype);
int datatypeLength = columnRef.getLength();
if( !allowsZeroStringLength && datatypeLength == 0 && DatatypeProcessor.DEFAULT_DATATYPE.equalsIgnoreCase(dTypeName) ) {
columnRef.setLength(DatatypeProcessor.DEFAULT_DATATYPE_LENGTH);
} else {
columnRef.setLength(datatypeLength);
}
}
// Set Description
if( columnRef.getDescription() != null ) {
createAnnotation(column, columnRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,columnRef,column);
return column;
}
private NullableType getNullableType(String value) {
if( NULLABLE.NULLABLE.equalsIgnoreCase(value) ) {
return NullableType.NULLABLE_LITERAL;
}
if( NULLABLE.NO_NULLS.equalsIgnoreCase(value) ) {
return NullableType.NO_NULLS_LITERAL;
}
return NullableType.NULLABLE_UNKNOWN_LITERAL;
}
private SearchabilityType getSearchabilityType(String value) {
if( SEARCHABILITY.UNSEARCHABLE.equalsIgnoreCase(value) ) {
return SearchabilityType.UNSEARCHABLE_LITERAL;
}
if( SEARCHABILITY.ALL_EXCEPT_LIKE.equalsIgnoreCase(value) ) {
return SearchabilityType.ALL_EXCEPT_LIKE_LITERAL;
}
if( SEARCHABILITY.LIKE_ONLY.equalsIgnoreCase(value) ) {
return SearchabilityType.LIKE_ONLY_LITERAL;
}
return SearchabilityType.SEARCHABLE_LITERAL;
}
private void 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);
}
}
// Set Description
if( pkRef.getDescription() != null ) {
createAnnotation(primaryKey, pkRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,pkRef,primaryKey);
}
public void 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 = ModelerCore.getModelEditor().getName((UniqueKey)key);
if( keyName.equalsIgnoreCase(ukRefName) ) {
foreignKey.setUniqueKey((UniqueKey)key);
}
}
}
}
// Set Description
if( fkRef.getDescription() != null ) {
createAnnotation(foreignKey, fkRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,fkRef,foreignKey);
}
private void 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);
}
}
// Set Description
if( apRef.getDescription() != null ) {
createAnnotation(accessPattern, apRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,apRef,accessPattern);
}
private void createUniqueConstraint( RelationalReference ref, BaseTable baseTable, ModelResource modelResource) {
CoreArgCheck.isInstanceOf(RelationalUniqueConstraint.class, ref);
RelationalUniqueConstraint ucRef = (RelationalUniqueConstraint)ref;
// Create the unique constraint
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);
}
}
// Set Description
if( ucRef.getDescription() != null ) {
createAnnotation(uniqueConstraint, ucRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,ucRef,uniqueConstraint);
}
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;
}
private BaseTable getTable(String tableName, ModelResource modelResource) {
try {
for (EObject eObj : modelResource.getEmfResource().getContents() ) {
String eObjName = ModelerCore.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.relationalModelFactory_error_finding_table_named, tableName));
}
return null;
}
/**
* @param ref the procedure object
* @param modelResource the model resource
* @return the object
*/
public EObject createProcedure( final RelationalReference ref, ModelResource modelResource) throws ModelWorkspaceException {
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()));
modelResource.getEmfResource().getContents().add(procedure);
// Set Description
if( procedureRef.getDescription() != null ) {
createAnnotation(procedure, procedureRef.getDescription(), modelResource);
}
// Add Columns
for( RelationalParameter paramRef : procedureRef.getParameters()) {
createParameter(paramRef, procedure, modelResource);
}
if( procedureRef.getResultSet() != null ) {
createResultSet(procedureRef.getResultSet(), procedure, modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,procedureRef,procedure);
return procedure;
}
/**
* @param ref the parameter object
* @param procedure the parent procedure
* @param modelResource the model resource
* @return the object
*/
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.setLength(parameterRef.getLength());
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 = ModelerCore.getModelEditor().getName(datatype);
int datatypeLength = parameterRef.getLength();
if( !allowsZeroStringLength && datatypeLength == 0 && DatatypeProcessor.DEFAULT_DATATYPE.equalsIgnoreCase(dTypeName) ) {
parameter.setLength(DatatypeProcessor.DEFAULT_DATATYPE_LENGTH);
} else {
parameter.setLength(datatypeLength);
}
}
if( parameterRef.getDescription() != null) {
createAnnotation(parameter, parameterRef.getDescription(), modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,parameterRef,parameter);
return parameter;
}
protected void applyTableExtensionProperties(RelationalTable tableRef, BaseTable baseTable, boolean isVirtual) {
if( isVirtual ) return;
// Set Extension Properties here
final RelationalModelExtensionAssistant assistant = getExtensionAssistant();
if( assistant != null ) {
try {
assistant.setPropertyValue(baseTable,
BASE_TABLE_EXT_PROPERTIES.NATIVE_QUERY,
tableRef.getNativeQuery() );
} catch (Exception ex) {
RelationalPlugin.Util.log(IStatus.ERROR, ex,
NLS.bind(Messages.relationalModelFactory_error_setting_extension_props_on_0, tableRef.getName()));
}
}
}
protected void applyProcedureExtensionProperties(RelationalProcedure procedureRef, Procedure procedure) {
// Set Extension Properties here
final RelationalModelExtensionAssistant assistant = getExtensionAssistant();
if( assistant != null ) {
try {
final Collection<ModelExtensionPropertyDefinition> extProps = assistant.getPropertyDefinitions(procedure);
for (final ModelExtensionPropertyDefinition propDefn : extProps) {
final String id = propDefn.getId();
if (PROCEDURE_EXT_PROPERTIES.NON_PREPARED.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.NON_PREPARED,
Boolean.toString(procedureRef.isNonPrepared()));
} else if (PROCEDURE_EXT_PROPERTIES.NATIVE_QUERY.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.NATIVE_QUERY,
procedureRef.getNativeQuery());
} else if (PROCEDURE_EXT_PROPERTIES.DETERMINISTIC.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.DETERMINISTIC,
Boolean.toString(procedureRef.isDeterministic()));
} else if (PROCEDURE_EXT_PROPERTIES.NULL_ON_NULL.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.NULL_ON_NULL,
Boolean.toString(procedureRef.isReturnsNullOnNull()));
} else if (PROCEDURE_EXT_PROPERTIES.VARARGS.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.VARARGS,
Boolean.toString(procedureRef.isVariableArguments()));
} else if (PROCEDURE_EXT_PROPERTIES.AGGREGATE.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.AGGREGATE,
Boolean.toString(procedureRef.isAggregate()));
} else if (PROCEDURE_EXT_PROPERTIES.ALLOWS_DISTINCT.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.ALLOWS_DISTINCT,
Boolean.toString(procedureRef.isAllowsDistinct()));
} else if (PROCEDURE_EXT_PROPERTIES.ALLOWS_ORDER_BY.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.ALLOWS_ORDER_BY,
Boolean.toString(procedureRef.isAllowsOrderBy()));
} else if (PROCEDURE_EXT_PROPERTIES.ANALYTIC.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.ANALYTIC,
Boolean.toString(procedureRef.isAnalytic()));
} else if (PROCEDURE_EXT_PROPERTIES.DECOMPOSABLE.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.DECOMPOSABLE,
Boolean.toString(procedureRef.isDecomposable()));
} else if (PROCEDURE_EXT_PROPERTIES.JAVA_CLASS.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.JAVA_CLASS,
procedureRef.getJavaClassName());
} else if (PROCEDURE_EXT_PROPERTIES.USES_DISTINCT_ROWS.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.USES_DISTINCT_ROWS,
Boolean.toString(procedureRef.isUseDistinctRows()));
} else if (PROCEDURE_EXT_PROPERTIES.JAVA_METHOD.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.JAVA_METHOD,
procedureRef.getJavaMethodName());
} else if (PROCEDURE_EXT_PROPERTIES.UDF_JAR_PATH.equals(id)) {
assistant.setPropertyValue(procedure, PROCEDURE_EXT_PROPERTIES.UDF_JAR_PATH, procedureRef.getUdfJarPath());
} else if (PROCEDURE_EXT_PROPERTIES.FUNCTION_CATEGORY.equals(id)) {
assistant.setPropertyValue(procedure,
PROCEDURE_EXT_PROPERTIES.FUNCTION_CATEGORY,
procedureRef.getFunctionCategory());
}
}
} catch (Exception ex) {
RelationalPlugin.Util.log(IStatus.ERROR, ex,
NLS.bind(Messages.relationalModelFactory_error_setting_extension_props_on_0, procedureRef.getName()));
}
}
}
/**
* @param ref the result set object
* @param procedure the parent procedure
* @param modelResource the model resource
* @return the 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());
// Set Description
if( resultSetRef.getDescription() != null ) {
createAnnotation(result, resultSetRef.getDescription(), modelResource);
}
// Add Columns
for( RelationalColumn colRef : resultSetRef.getColumns()) {
createColumn(colRef, result, modelResource);
}
// Apply Extension Properties
processExtensionProperties(modelResource,resultSetRef,result);
return result;
}
/**
* @param ref the relational index object
* @param modelResource the model resource
* @return the index object
*/
public EObject createIndex( RelationalReference ref, ModelResource modelResource) throws ModelWorkspaceException {
CoreArgCheck.isInstanceOf(RelationalIndex.class, ref);
RelationalIndex indexRef = (RelationalIndex)ref;
Index index = FACTORY.createIndex();
index.setName(indexRef.getName());
index.setNameInSource(indexRef.getNameInSource());
index.setFilterCondition(indexRef.getFilterCondition());
index.setAutoUpdate(indexRef.isAutoUpdate());
index.setNullable(indexRef.isNullable());
index.setUnique(indexRef.isUnique());
modelResource.getEmfResource().getContents().add(index);
// Set Description
if( indexRef.getDescription() != null ) {
createAnnotation(index, indexRef.getDescription(), modelResource);
}
// 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);
}
}
// Apply Extension Properties
processExtensionProperties(modelResource,indexRef,index);
return index;
}
public void setMatTableReference( Table table, RelationalTable tableRef, ModelResource modelResource) throws CoreException {
IProject project = modelResource.getCorrespondingResource().getProject();
IPath modelPath = new Path(tableRef.getMaterializedTableModelPath());
ModelResource[] mResources = ModelerCore.getModelWorkspace().getModelResources();
ModelResource referencedMR = null;
for( ModelResource mr : mResources ) {
IPath fullPath = mr.getCorrespondingResource().getFullPath();
if( fullPath.equals(modelPath) ) {
referencedMR = mr;
break;
}
}
if( referencedMR != null ) {
BaseTable matTable = getTable(tableRef.getMaterializedTable(), referencedMR);
if( matTable != null) {
table.setMaterializedTable(matTable);
}
}
}
private DirectionKind getDirectionKind(String value) {
if( DIRECTION.IN.equalsIgnoreCase(value) ) {
return DirectionKind.IN_LITERAL;
}
if( DIRECTION.IN_OUT.equalsIgnoreCase(value) ) {
return DirectionKind.INOUT_LITERAL;
}
if( DIRECTION.OUT.equalsIgnoreCase(value) ) {
return DirectionKind.OUT_LITERAL;
}
if( DIRECTION.RETURN.equalsIgnoreCase(value) ) {
return DirectionKind.RETURN_LITERAL;
}
return DirectionKind.UNKNOWN_LITERAL;
}
private ProcedureUpdateCount getUpdateCount(String value) {
if( ProcedureUpdateCount.AUTO_LITERAL.getName().equalsIgnoreCase(value) ) {
return ProcedureUpdateCount.AUTO_LITERAL;
}
if( ProcedureUpdateCount.ONE_LITERAL.getName().equalsIgnoreCase(value) ) {
return ProcedureUpdateCount.ONE_LITERAL;
}
if( ProcedureUpdateCount.MULTIPLE_LITERAL.getName().equalsIgnoreCase(value) ) {
return ProcedureUpdateCount.MULTIPLE_LITERAL;
}
if( ProcedureUpdateCount.ZERO_LITERAL.getName().equalsIgnoreCase(value) ) {
return ProcedureUpdateCount.ZERO_LITERAL;
}
return ProcedureUpdateCount.AUTO_LITERAL;
}
private MultiplicityKind getMultiplictyKind(String value) {
if( MultiplicityKind.MANY_LITERAL.getName().equalsIgnoreCase(value) ) {
return MultiplicityKind.MANY_LITERAL;
}
if( MultiplicityKind.ONE_LITERAL.getName().equalsIgnoreCase(value) ) {
return MultiplicityKind.ONE_LITERAL;
}
if( MultiplicityKind.ZERO_TO_ONE_LITERAL.getName().equalsIgnoreCase(value) ) {
return MultiplicityKind.ZERO_TO_ONE_LITERAL;
}
if( MultiplicityKind.ZERO_TO_MANY_LITERAL.getName().equalsIgnoreCase(value) ) {
return MultiplicityKind.ZERO_TO_MANY_LITERAL;
}
return MultiplicityKind.UNSPECIFIED_LITERAL;
}
/**
* @param eObject the target object
* @param description the description
* @param modelResource the model resource
*/
public void createAnnotation( 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.relationalModelFactory_error_adding_desciption_to_0, eObject));
}
}
}
/**
* @param eObject the model object whose relational reference is being requested (cannot be <code>null</code>)
* @return the relational reference or <code>null</code> if not found
*/
public RelationalReference getRelationalObject(EObject eObject) {
if( eObject instanceof BaseTable) {
BaseTable theTable = (BaseTable)eObject;
String name = ModelerCore.getModelEditor().getName(eObject);
RelationalTable relTable = new RelationalTable(name);
relTable.setSupportsUpdate(theTable.isSupportsUpdate());
relTable.setMaterialized(theTable.isMaterialized());
relTable.setNameInSource(theTable.getNameInSource());
relTable.setSystem(theTable.isSystem());
relTable.setCardinality(theTable.getCardinality());
final EList<EObject> tableColumns = theTable.getColumns();
for( EObject column : tableColumns) {
relTable.addColumn((RelationalColumn)getRelationalObject(column));
}
transferDescription(theTable, relTable);
return relTable;
} else if( eObject instanceof View ) {
} else if( eObject instanceof Procedure ) {
} else if( eObject instanceof Index ) {
Index theIndex = (Index)eObject;
String name = ModelerCore.getModelEditor().getName(eObject);
RelationalIndex relIndex = new RelationalIndex(name);
relIndex.setNameInSource(theIndex.getNameInSource());
relIndex.setFilterCondition(theIndex.getFilterCondition());
relIndex.setAutoUpdate(theIndex.isAutoUpdate());
relIndex.setNullable(theIndex.isNullable());
relIndex.setUnique(theIndex.isUnique());
transferDescription(theIndex, relIndex);
// Add the columns in the correct order
final EList<EObject> indexColumns = theIndex.getColumns();
for (EObject column : indexColumns ) {
relIndex.addColumn((RelationalColumn)getRelationalObject(column));
}
return relIndex;
} else if( eObject instanceof Column) {
Column theColumn = (Column)eObject;
String name = ModelerCore.getModelEditor().getName(theColumn);
RelationalColumn relColumn = new RelationalColumn(name);
transferDescription(theColumn, relColumn);
return relColumn;
}
return null;
}
private void transferDescription(EObject eObject, RelationalReference relationalRef) {
try {
// Set Description
String desc = ModelerCore.getModelEditor().getDescription(eObject);
if( desc != null ) {
relationalRef.setDescription(desc);
}
} catch (ModelerCoreException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
}
/**
* 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
*
*/
private void processExtensionProperties(ModelResource modelResource, RelationalReference relationalEntity, EObject 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
try {
applyMedIfNecessary(modelResource,assistant);
} catch (Exception e) {
//DdlImporterPlugin.UTIL.log(IStatus.ERROR,e,DdlImporterI18n.ERROR_APPLYING_MED_TO_MODEL);
}
String namespacedId = null;
try {
namespacedId = assistant.getNamespacePrefix()+':'+propName;
assistant.setPropertyValue(eObject, namespacedId, propValue);
} catch (Exception ex) {
//DdlImporterPlugin.UTIL.log(IStatus.ERROR,ex,DdlImporterI18n.ERROR_SETTING_PROPERTY_VALUE+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) throws Exception {
if (modelResource != null && !modelResource.isReadOnly()) {
if(!assistant.supportsMyNamespace(modelResource)) {
assistant.saveModelExtensionDefinition(modelResource);
}
}
}
/**
* 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()) {
//DdlImporterPlugin.UTIL.log(IStatus.WARNING,DdlImporterI18n.WARNING_ASSISTANT_FOR_METACLASS_NOT_FOUND+eObjectClassName);
return null;
}
// find the assistant for the property
for (ModelExtensionAssistant assistant : assistants) {
// Prepend the assistant namespace to the propertyId, since it doesnt have one
String namespacedId = propId; // assistant.getNamespacePrefix()+':'+propId;
if(hasMatchingPropertyName(assistant.getModelExtensionDefinition(), eObjectClassName, namespacedId)) {
return ((assistant instanceof ModelObjectExtensionAssistant) ? (ModelObjectExtensionAssistant)assistant : null);
}
}
//DdlImporterPlugin.UTIL.log(IStatus.WARNING,DdlImporterI18n.WARNING_ASSISTANT_FOR_PROPERTY_NOT_FOUND+propId);
return null;
}
/**
* 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;
}
public boolean allowsZeroStringLength() {
return allowsZeroStringLength;
}
public void setAllowsZeroStringLength(boolean allowsZeroStringLength) {
this.allowsZeroStringLength = allowsZeroStringLength;
}
}