/*
* 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.transformation.ui.wizards.file;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
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.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.core.designer.util.I18nUtil;
import org.teiid.core.designer.util.StringUtilities;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.workspace.ModelResource;
import org.teiid.designer.core.workspace.ModelWorkspaceException;
import org.teiid.designer.core.workspace.ModelWorkspaceItem;
import org.teiid.designer.core.workspace.ModelWorkspaceManager;
import org.teiid.designer.datatools.connection.ConnectionInfoHelper;
import org.teiid.designer.datatools.connection.ConnectionInfoProviderFactory;
import org.teiid.designer.datatools.connection.DataSourceConnectionHelper;
import org.teiid.designer.datatools.connection.IConnectionInfoProvider;
import org.teiid.designer.datatools.profiles.flatfile.FlatFileConnectionInfoProvider;
import org.teiid.designer.datatools.profiles.flatfile.FlatFileUrlConnectionInfoProvider;
import org.teiid.designer.datatools.profiles.ws.IWSProfileConstants;
import org.teiid.designer.datatools.profiles.ws.WSConnectionInfoProvider;
import org.teiid.designer.datatools.ui.DatatoolsUiConstants;
import org.teiid.designer.runtime.spi.ITeiidServer;
import org.teiid.designer.transformation.ui.UiConstants;
import org.teiid.designer.ui.common.util.WidgetUtil;
import org.teiid.designer.ui.editors.ModelEditor;
import org.teiid.designer.ui.editors.ModelEditorManager;
import org.teiid.designer.ui.viewsupport.ModelIdentifier;
import org.teiid.designer.ui.viewsupport.ModelUtilities;
/**
* @since 8.0
*/
public class TeiidMetadataImportProcessor implements UiConstants {
private static final String I18N_PREFIX = I18nUtil.getPropertyPrefix(TeiidMetadataImportProcessor.class);
protected static final String DEFAULT_EXTENSION_LCASE = ".xmi"; //$NON-NLS-1$
protected static String FILE_DS_TYPE = "file"; //$NON-NLS-1$
protected static String WS_DS_TYPE = "webservice"; //$NON-NLS-1$
private static String getString( final String id ) {
return Util.getString(I18N_PREFIX + id);
}
private static String getString( final String id, final Object param ) {
return Util.getString(I18N_PREFIX + id, param);
}
TeiidMetadataImportInfo info;
ModelResource sourceModel;
ModelResource viewModel;
IStatus createStatus;
Shell shell;
public TeiidMetadataImportProcessor(TeiidMetadataImportInfo info, Shell shell) {
super();
this.info = info;
this.shell = shell;
createStatus = Status.OK_STATUS;
}
public IStatus execute() {
final WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
@Override
public void execute( final IProgressMonitor theMonitor ) {
theMonitor.beginTask(getString("task.creatingSourceModel", info.getSourceModelName()), 100); //$NON-NLS-1$
if( info.sourceModelExists() ) {
createStatus = createProceduresInExistingSourceModelInTxn(theMonitor);
} else {
createStatus = createSourceModelInTxn(theMonitor);
if( createStatus.isOK() ) {
createStatus = createProceduresInExistingSourceModelInTxn(theMonitor);
}
}
if( info.viewModelExists() ) {
createStatus = createViewsInExistingModelInTxn(theMonitor);
} else {
createStatus = createViewModelInTxn(theMonitor);
}
theMonitor.worked(50);
if( createStatus.isOK() ) {
handleCreateDataSource();
}
theMonitor.done();
}
};
try {
new ProgressMonitorDialog(shell).run(false, true, op);
} catch (final InterruptedException e) {
} catch (final InvocationTargetException e) {
UiConstants.Util.log(e.getTargetException());
} catch (final Exception err) {
Throwable t = err;
if (err instanceof InvocationTargetException) {
t = err.getCause();
}
WidgetUtil.showError(t);
}
return createStatus;
}
private IStatus createSourceModelInTxn(IProgressMonitor monitor) {
boolean requiredStart = ModelerCore.startTxn(true, true, "Import Teiid Metadata Create Source Model", this); //$NON-NLS-1$
boolean succeeded = false;
try {
sourceModel = createRelationalFileSourceModel();
monitor.worked(10);
// Inject the connection profile info into the model
if (this.info.getConnectionProfile() != null) {
addConnectionProfileInfoToModel(sourceModel, info);
}
monitor.subTask(getString("task.savingSourceModel", sourceModel.getItemName()) ); //$NON-NLS-1$
try {
ModelUtilities.saveModelResource(sourceModel, monitor, false, this);
} catch (Exception e) {
throw new InvocationTargetException(e);
}
monitor.worked(10);
if( createStatus.isOK() && sourceModel != null ) {
ModelEditorManager.openInEditMode(sourceModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR);
}
succeeded = true;
} catch (Exception e) {
IStatus status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, getString("exceptionMessage_2", info.getSourceModelName()), e); //$NON-NLS-1$
UiConstants.Util.log(status);
MessageDialog.openError(shell, getString("exceptionMessage_2", info.getSourceModelName()), e.getMessage()); //$NON-NLS-1$
return status;
} finally {
// if we started the txn, commit it.
if (requiredStart) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
monitor.worked(10);
if( createStatus.isOK() && sourceModel != null ) {
ModelEditorManager.openInEditMode(sourceModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR);
}
monitor.worked(10);
return Status.OK_STATUS;
}
protected void addConnectionProfileInfoToModel(ModelResource sourceModel, TeiidMetadataImportInfo info) throws ModelWorkspaceException {
// Inject the connection profile info into the model
if (info.getConnectionProfile() != null) {
IConnectionInfoProvider provider = null;
if( getInfo().isFlatFileLocalMode() ) {
provider = new FlatFileConnectionInfoProvider();
} else if( getInfo().isFlatFileUrlMode() ) {
if( IWSProfileConstants.TEIID_WS_CONNECTION_PROFILE_ID.equalsIgnoreCase(info.getConnectionProfile().getProviderId()) ) {
provider = new WSConnectionInfoProvider();
} else {
provider = new FlatFileUrlConnectionInfoProvider();
}
}
if( provider != null ) {
provider.setConnectionInfo(sourceModel, info.getConnectionProfile());
}
String jndiName = info.getJBossJndiName();
if( !StringUtilities.isEmpty(jndiName) ) {
ConnectionInfoHelper helper = new ConnectionInfoHelper();
helper.setJNDIName(sourceModel, jndiName);
}
}
}
private IStatus createViewsInExistingModelInTxn(IProgressMonitor monitor) {
boolean requiredStart = ModelerCore.startTxn(true, true, "Import Teiid Metadata Create View Tables", this); //$NON-NLS-1$
boolean succeeded = false;
try {
monitor.subTask(getString("task.creatingViewTablesInViewModel") + info.getViewModelName()); //$NON-NLS-1$
viewModel = createViewsInExistingModel(sourceModel.getPath().removeFileExtension().lastSegment());
monitor.worked(10);
succeeded = true;
} catch (Exception e) {
IStatus status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, getString("exceptionMessage_3", info.getViewModelName()), e); //$NON-NLS-1$
UiConstants.Util.log(status);
MessageDialog.openError(shell, getString("exceptionMessage_3", info.getViewModelName()), e.getMessage()); //$NON-NLS-1$
return status;
} finally {
// if we started the txn, commit it.
if (requiredStart) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
return Status.OK_STATUS;
}
private IStatus createViewModelInTxn(IProgressMonitor monitor) {
ModelResource viewModel = null;
boolean requiredStart = ModelerCore.startTxn(true, true, "Import Teiid Metadata Create View Model", this); //$NON-NLS-1$
boolean succeeded = false;
try {
monitor.subTask(getString("task.creatingViewTablesInNewViewModel") + info.getViewModelName()); //$NON-NLS-1$
viewModel = createViewsInNewModel(sourceModel.getPath().removeFileExtension().lastSegment());
monitor.worked(40);
if( createStatus.isOK() && sourceModel != null ) {
try {
ModelUtilities.saveModelResource(viewModel, monitor, false, this);
} catch (Exception e) {
throw new InvocationTargetException(e);
}
}
monitor.worked(10);
if( createStatus.isOK() && viewModel != null ) {
ModelEditorManager.openInEditMode(viewModel, true, org.teiid.designer.ui.UiConstants.ObjectEditor.IGNORE_OPEN_EDITOR);
}
succeeded = true;
} catch (Exception e) {
IStatus status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, getString("exceptionMessage_4", info.getViewModelName()), e); //$NON-NLS-1$
UiConstants.Util.log(status);
MessageDialog.openError(shell, getString("exceptionMessage_4", info.getViewModelName()), e.getMessage()); //$NON-NLS-1$
return status;
} finally {
// if we started the txn, commit it.
if (requiredStart) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
return Status.OK_STATUS;
}
protected ModelResource createViewsInExistingModel(String relationalModelName) throws ModelerCoreException {
if( info.getViewModelLocation() != null && info.getViewModelName() != null ) {
IFile viewIFile = null;
if( this.viewModel != null ) {
viewIFile = (IFile)this.viewModel.getCorrespondingResource();
} else {
IPath modelPath = info.getViewModelLocation().append(info.getViewModelName());
if( !modelPath.toString().toUpperCase().endsWith(".XMI")) { //$NON-NLS-1$
modelPath = modelPath.addFileExtension(".xmi"); //$NON-NLS-1$
}
ModelWorkspaceItem item = ModelWorkspaceManager.getModelWorkspaceManager().findModelWorkspaceItem(modelPath, IResource.FILE);
viewIFile = (IFile)item.getCorrespondingResource();
}
ModelEditor editor = ModelEditorManager.getModelEditorForFile( viewIFile, true);
if (editor != null) {
boolean isDirty = editor.isDirty();
FlatFileViewModelFactory factory = new FlatFileViewModelFactory();
for( TeiidMetadataFileInfo info : this.info.getFileInfos()) {
if( info.doProcess() ) {
factory.createViewTable(editor.getModelResource(), info, relationalModelName);
}
}
editor.getModelResource().save(null, true);
if (!isDirty && editor.isDirty()) {
editor.doSave(new NullProgressMonitor());
}
return editor.getModelResource();
}
}
return null;
}
private ModelResource createRelationalFileSourceModel() throws ModelerCoreException {
FlatFileRelationalModelFactory factory = new FlatFileRelationalModelFactory();
String modelName = this.info.getSourceModelName();
if (!modelName.toLowerCase().endsWith(DEFAULT_EXTENSION_LCASE)) {
modelName = modelName + DEFAULT_EXTENSION_LCASE;
}
return factory.createRelationalModel(this.info.getSourceModelLocation(), modelName);
}
protected ModelResource createViewsInNewModel(String sourceModelName) throws ModelerCoreException {
FlatFileViewModelFactory factory = new FlatFileViewModelFactory();
String modelName = this.info.getViewModelName();
if (!modelName.toLowerCase().endsWith(DEFAULT_EXTENSION_LCASE)) {
modelName = modelName + DEFAULT_EXTENSION_LCASE;
}
ModelResource modelResource = factory.createViewRelationalModel(this.info.getViewModelLocation(), modelName);
for( TeiidMetadataFileInfo info : this.info.getFileInfos()) {
if( info.doProcess() ) {
factory.createViewTable(modelResource, info, sourceModelName);
}
}
return modelResource;
}
private IStatus createProceduresInExistingSourceModelInTxn(IProgressMonitor monitor) {
boolean requiredStart = ModelerCore.startTxn(true, true, "Import Teiid Metadata Create View Tables", this); //$NON-NLS-1$
boolean succeeded = false;
try {
monitor.subTask(getString("task.creatingProceduresInSourceModel") + info.getSourceModelName()); //$NON-NLS-1$
sourceModel = addProcedureToRelationalSourceModel();
monitor.worked(10);
succeeded = true;
} catch (Exception e) {
IStatus status = new Status(IStatus.ERROR, UiConstants.PLUGIN_ID,getString("exceptionMessage_3", info.getViewModelName()), e); //$NON-NLS-1$
UiConstants.Util.log(status);
MessageDialog.openError(shell, getString("exceptionMessage_3", info.getViewModelName()), e.getMessage()); //$NON-NLS-1$
return status;
} finally {
// if we started the txn, commit it.
if (requiredStart) {
if (succeeded) {
ModelerCore.commitTxn();
} else {
ModelerCore.rollbackTxn();
}
}
}
return Status.OK_STATUS;
}
protected ModelResource addProcedureToRelationalSourceModel() throws ModelerCoreException {
if( info.getSourceModelLocation() != null && info.getSourceModelName() != null ) {
IFile sourceIFile = null;
if( this.sourceModel != null ) {
sourceIFile = (IFile)this.sourceModel.getCorrespondingResource();
} else {
IPath modelPath = info.getSourceModelLocation().append(info.getSourceModelName());
if( !modelPath.toString().toUpperCase().endsWith(".XMI")) { //$NON-NLS-1$
modelPath = modelPath.addFileExtension("xmi"); //$NON-NLS-1$
}
ModelWorkspaceItem item = ModelWorkspaceManager.getModelWorkspaceManager().findModelWorkspaceItem(modelPath, IResource.FILE);
sourceIFile = (IFile)item.getCorrespondingResource();
}
ModelEditor editor = ModelEditorManager.getModelEditorForFile( sourceIFile, true);
if (editor != null) {
ModelResource mr = editor.getModelResource();
boolean isDirty = editor.isDirty();
FlatFileRelationalModelFactory factory = new FlatFileRelationalModelFactory();
if(info.isFlatFileLocalMode() || info.isXmlLocalFileMode()) {
factory.addMissingProcedure(mr, FlatFileRelationalModelFactory.GET_TEXT_FILES);
} else if(info.isFlatFileUrlMode()) {
factory.addMissingProcedure(mr, FlatFileRelationalModelFactory.INVOKE_HTTP);
}
mr.save(null, true);
if (!isDirty && editor.isDirty()) {
editor.doSave(new NullProgressMonitor());
}
return mr;
}
}
return null;
}
protected void handleCreateDataSource() {
if( info.doCreateDataSource() && DataSourceConnectionHelper.isServerConnected() ) {
ITeiidServer teiidServer = DataSourceConnectionHelper.getServer();
String dsName = info.getJBossJndiName();
String jndiName = info.getJBossJndiName();
DataSourceConnectionHelper helper = new DataSourceConnectionHelper(this.sourceModel, info.getConnectionProfile());
Properties connProps = helper.getModelConnectionProperties();
String dsType = helper.getDataSourceType();
try {
teiidServer.getOrCreateDataSource(dsName, jndiName, dsType, connProps);
} catch (Exception e) {
DatatoolsUiConstants.UTIL.log(e);
}
}
}
public TeiidMetadataImportInfo getInfo() {
return this.info;
}
protected ModelResource getSourceModel() {
return this.sourceModel;
}
}