Java tutorial
/*! * Copyright 2010 - 2015 Pentaho Corporation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.pentaho.di.trans.steps.mongodboutput; import com.mongodb.DBObject; import com.mongodb.MongoClient; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.pentaho.di.core.Const; import org.pentaho.di.core.Props; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.row.RowMeta; import org.pentaho.di.core.row.RowMetaInterface; import org.pentaho.di.core.row.ValueMetaInterface; import org.pentaho.di.core.row.value.ValueMetaFactory; import org.pentaho.di.core.variables.VariableSpace; import org.pentaho.di.core.variables.Variables; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.trans.TransMeta; import org.pentaho.di.trans.step.BaseStepMeta; import org.pentaho.di.trans.step.StepDialogInterface; import org.pentaho.di.ui.core.dialog.ErrorDialog; import org.pentaho.di.ui.core.dialog.ShowMessageDialog; import org.pentaho.di.ui.core.widget.ColumnInfo; import org.pentaho.di.ui.core.widget.PasswordTextVar; import org.pentaho.di.ui.core.widget.TableView; import org.pentaho.di.ui.core.widget.TextVar; import org.pentaho.di.ui.trans.step.BaseStepDialog; import org.pentaho.mongo.NamedReadPreference; import org.pentaho.mongo.wrapper.MongoClientWrapper; import org.pentaho.mongo.wrapper.MongoWrapperUtil; import java.security.PrivilegedActionException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Dialog class for the MongoDB output step * * @author Mark Hall (mhall{[at]}pentaho{[dot]}com) * @version $Revision$ */ public class MongoDbOutputDialog extends BaseStepDialog implements StepDialogInterface { private static final Class<?> PKG = MongoDbOutputMeta.class; protected MongoDbOutputMeta m_currentMeta; protected MongoDbOutputMeta m_originalMeta; /** * various UI bits and pieces for the dialog */ private Label m_stepnameLabel; private Text m_stepnameText; // The tabs of the dialog private CTabFolder m_wTabFolder; private CTabItem m_wConfigTab; private CTabItem m_wOutputOptionsTab; private CTabItem m_wMongoFieldsTab; private Button m_getFieldsBut; private Button m_previewDocStructBut; private CTabItem m_wMongoIndexesTab; private Button m_showIndexesBut; private TextVar m_hostnameField; private TextVar m_portField; private Button m_useAllReplicaSetMembersBut; private TextVar m_authDbName; private TextVar m_usernameField; private TextVar m_passField; private Button m_kerberosBut; private TextVar m_connectTimeout; private TextVar m_socketTimeout; private CCombo m_dbNameField; private Button m_getDBsBut; private CCombo m_collectionField; private Button m_getCollectionsBut; private TextVar m_batchInsertSizeField; private Button m_truncateBut; private Button m_updateBut; private Button m_upsertBut; private Button m_multiBut; private Button m_modifierUpdateBut; private CCombo m_writeConcern; private TextVar m_wTimeout; private Button m_journalWritesCheck; private CCombo m_readPreference; private TextVar m_writeRetries; private TextVar m_writeRetryDelay; private TableView m_mongoFieldsView; private TableView m_mongoIndexesView; public MongoDbOutputDialog(Shell parent, Object in, TransMeta tr, String name) { super(parent, (BaseStepMeta) in, tr, name); m_currentMeta = (MongoDbOutputMeta) in; m_originalMeta = (MongoDbOutputMeta) m_currentMeta.clone(); } @Override public String open() { Shell parent = getParent(); Display display = parent.getDisplay(); shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX); props.setLook(shell); setShellImage(shell, m_currentMeta); // used to listen to a text field (m_wStepname) ModifyListener lsMod = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_currentMeta.setChanged(); } }; changed = m_currentMeta.hasChanged(); FormLayout formLayout = new FormLayout(); formLayout.marginWidth = Const.FORM_MARGIN; formLayout.marginHeight = Const.FORM_MARGIN; shell.setLayout(formLayout); shell.setText(getString("MongoDbOutputDialog.Shell.Title")); //$NON-NLS-1$ int middle = props.getMiddlePct(); int margin = Const.MARGIN; // Stepname line m_stepnameLabel = new Label(shell, SWT.RIGHT); m_stepnameLabel.setText(getString("MongoDbOutputDialog.StepName.Label")); //$NON-NLS-1$ props.setLook(m_stepnameLabel); FormData fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(middle, -margin); fd.top = new FormAttachment(0, margin); m_stepnameLabel.setLayoutData(fd); m_stepnameText = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); m_stepnameText.setText(stepname); props.setLook(m_stepnameText); m_stepnameText.addModifyListener(lsMod); // format the text field fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(0, margin); fd.right = new FormAttachment(100, 0); m_stepnameText.setLayoutData(fd); m_wTabFolder = new CTabFolder(shell, SWT.BORDER); props.setLook(m_wTabFolder, Props.WIDGET_STYLE_TAB); m_wTabFolder.setSimple(false); // Start of the config tab m_wConfigTab = new CTabItem(m_wTabFolder, SWT.NONE); m_wConfigTab.setText(getString("MongoDbOutputDialog.ConfigTab.TabTitle")); //$NON-NLS-1$ Composite wConfigComp = new Composite(m_wTabFolder, SWT.NONE); props.setLook(wConfigComp); FormLayout configLayout = new FormLayout(); configLayout.marginWidth = 3; configLayout.marginHeight = 3; wConfigComp.setLayout(configLayout); // hostname line Label hostnameLab = new Label(wConfigComp, SWT.RIGHT); hostnameLab.setText(getString("MongoDbOutputDialog.Hostname.Label")); //$NON-NLS-1$ hostnameLab.setToolTipText(getString("MongoDbOutputDialog.Hostname.TipText")); //$NON-NLS-1$ props.setLook(hostnameLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, margin); fd.right = new FormAttachment(middle, -margin); hostnameLab.setLayoutData(fd); m_hostnameField = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_hostnameField); m_hostnameField.addModifyListener(lsMod); // set the tool tip to the contents with any env variables expanded m_hostnameField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_hostnameField.setToolTipText(transMeta.environmentSubstitute(m_hostnameField.getText())); } }); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(0, 0); fd.left = new FormAttachment(middle, 0); m_hostnameField.setLayoutData(fd); // port line Label portLab = new Label(wConfigComp, SWT.RIGHT); portLab.setText(getString("MongoDbOutputDialog.Port.Label")); //$NON-NLS-1$ portLab.setToolTipText(getString("MongoDbOutputDialog.Port.Label.TipText")); //$NON-NLS-1$ props.setLook(portLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_hostnameField, margin); fd.right = new FormAttachment(middle, -margin); portLab.setLayoutData(fd); m_portField = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_portField); m_portField.addModifyListener(lsMod); // set the tool tip to the contents with any env variables expanded m_portField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_portField.setToolTipText(transMeta.environmentSubstitute(m_portField.getText())); } }); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_hostnameField, margin); fd.left = new FormAttachment(middle, 0); m_portField.setLayoutData(fd); // Use all replica set members check box Label useAllReplicaLab = new Label(wConfigComp, SWT.RIGHT); useAllReplicaLab.setText(getString("MongoDbOutputDialog.UseAllReplicaSetMembers.Label")); //$NON-NLS-1$ useAllReplicaLab.setToolTipText(getString("MongoDbOutputDialog.UseAllReplicaSetMembers.TipText")); //$NON-NLS-1$ props.setLook(useAllReplicaLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(middle, -margin); fd.top = new FormAttachment(m_portField, margin); useAllReplicaLab.setLayoutData(fd); m_useAllReplicaSetMembersBut = new Button(wConfigComp, SWT.CHECK); props.setLook(m_useAllReplicaSetMembersBut); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_portField, margin); m_useAllReplicaSetMembersBut.setLayoutData(fd); // authentication database field Label authBdLab = new Label(wConfigComp, SWT.RIGHT); authBdLab.setText(getString("MongoDbOutputDialog.AuthenticationDatabaseName.Label")); //$NON-NLS-1$ props.setLook(authBdLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_useAllReplicaSetMembersBut, margin); fd.right = new FormAttachment(middle, -margin); authBdLab.setLayoutData(fd); m_authDbName = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_authDbName); m_authDbName.addModifyListener(lsMod); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_useAllReplicaSetMembersBut, margin); fd.left = new FormAttachment(middle, 0); m_authDbName.setLayoutData(fd); // username field Label userLab = new Label(wConfigComp, SWT.RIGHT); userLab.setText(getString("MongoDbOutputDialog.Username.Label")); //$NON-NLS-1$ props.setLook(userLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_authDbName, margin); fd.right = new FormAttachment(middle, -margin); userLab.setLayoutData(fd); m_usernameField = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_usernameField); m_usernameField.addModifyListener(lsMod); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_authDbName, margin); fd.left = new FormAttachment(middle, 0); m_usernameField.setLayoutData(fd); // password field Label passLab = new Label(wConfigComp, SWT.RIGHT); passLab.setText(getString("MongoDbOutputDialog.Password.Label")); //$NON-NLS-1$ props.setLook(passLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_usernameField, margin); fd.right = new FormAttachment(middle, -margin); passLab.setLayoutData(fd); m_passField = new PasswordTextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_passField); m_passField.addModifyListener(lsMod); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_usernameField, margin); fd.left = new FormAttachment(middle, 0); m_passField.setLayoutData(fd); // use kerberos authentication Label kerbLab = new Label(wConfigComp, SWT.RIGHT); kerbLab.setText(getString("MongoDbOutputDialog.Kerberos.Label")); //$NON-NLS-1$ props.setLook(kerbLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_passField, margin); fd.right = new FormAttachment(middle, -margin); kerbLab.setLayoutData(fd); m_kerberosBut = new Button(wConfigComp, SWT.CHECK); props.setLook(m_kerberosBut); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_passField, margin); m_kerberosBut.setLayoutData(fd); m_kerberosBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_passField.setEnabled(!m_kerberosBut.getSelection()); } }); // connection timeout Label connectTimeoutL = new Label(wConfigComp, SWT.RIGHT); connectTimeoutL.setText(getString("MongoDbOutputDialog.ConnectionTimeout.Label")); //$NON-NLS-1$ props.setLook(connectTimeoutL); connectTimeoutL.setToolTipText(getString("MongoDbOutputDialog.ConnectionTimeout.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, -margin); fd.top = new FormAttachment(m_kerberosBut, margin); fd.right = new FormAttachment(middle, -margin); connectTimeoutL.setLayoutData(fd); m_connectTimeout = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_connectTimeout); m_connectTimeout.addModifyListener(lsMod); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_kerberosBut, margin); fd.right = new FormAttachment(100, 0); m_connectTimeout.setLayoutData(fd); m_connectTimeout.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_connectTimeout.setToolTipText(transMeta.environmentSubstitute(m_connectTimeout.getText())); } }); // socket timeout Label socketTimeoutL = new Label(wConfigComp, SWT.RIGHT); socketTimeoutL.setText(getString("MongoDbOutputDialog.SocketTimeout.Label")); //$NON-NLS-1$ props.setLook(connectTimeoutL); socketTimeoutL.setToolTipText(getString("MongoDbOutputDialog.SocketTimeout.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, -margin); fd.top = new FormAttachment(m_connectTimeout, margin); fd.right = new FormAttachment(middle, -margin); socketTimeoutL.setLayoutData(fd); m_socketTimeout = new TextVar(transMeta, wConfigComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_socketTimeout); m_socketTimeout.addModifyListener(lsMod); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_connectTimeout, margin); fd.right = new FormAttachment(100, 0); m_socketTimeout.setLayoutData(fd); m_socketTimeout.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_socketTimeout.setToolTipText(transMeta.environmentSubstitute(m_socketTimeout.getText())); } }); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, 0); wConfigComp.setLayoutData(fd); wConfigComp.layout(); m_wConfigTab.setControl(wConfigComp); // --- start of the options tab m_wOutputOptionsTab = new CTabItem(m_wTabFolder, SWT.NONE); m_wOutputOptionsTab.setText("Output options"); //$NON-NLS-1$ Composite wOutputComp = new Composite(m_wTabFolder, SWT.NONE); props.setLook(wOutputComp); FormLayout outputLayout = new FormLayout(); outputLayout.marginWidth = 3; outputLayout.marginHeight = 3; wOutputComp.setLayout(outputLayout); // DB name Label dbNameLab = new Label(wOutputComp, SWT.RIGHT); dbNameLab.setText(getString("MongoDbOutputDialog.DBName.Label")); //$NON-NLS-1$ dbNameLab.setToolTipText(getString("MongoDbOutputDialog.DBName.TipText")); //$NON-NLS-1$ props.setLook(dbNameLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, margin); fd.right = new FormAttachment(middle, -margin); dbNameLab.setLayoutData(fd); m_getDBsBut = new Button(wOutputComp, SWT.PUSH | SWT.CENTER); props.setLook(m_getDBsBut); m_getDBsBut.setText(getString("MongoDbOutputDialog.GetDBs.Button")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(0, 0); m_getDBsBut.setLayoutData(fd); m_dbNameField = new CCombo(wOutputComp, SWT.BORDER); props.setLook(m_dbNameField); m_dbNameField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_currentMeta.setChanged(); m_dbNameField.setToolTipText(transMeta.environmentSubstitute(m_dbNameField.getText())); } }); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_passField, margin); fd.right = new FormAttachment(m_getDBsBut, -margin); m_dbNameField.setLayoutData(fd); m_getDBsBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setupDBNames(); } }); // collection line Label collectionLab = new Label(wOutputComp, SWT.RIGHT); collectionLab.setText(getString("MongoDbOutputDialog.Collection.Label")); //$NON-NLS-1$ collectionLab.setToolTipText(getString("MongoDbOutputDialog.Collection.TipText")); //$NON-NLS-1$ props.setLook(collectionLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_dbNameField, margin); fd.right = new FormAttachment(middle, -margin); collectionLab.setLayoutData(fd); m_getCollectionsBut = new Button(wOutputComp, SWT.PUSH | SWT.CENTER); props.setLook(m_getCollectionsBut); m_getCollectionsBut.setText(getString("MongoDbOutputDialog.GetCollections.Button")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_dbNameField, 0); m_getCollectionsBut.setLayoutData(fd); m_getCollectionsBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // setupMappingNamesForTable(false); setupCollectionNamesForDB(false); } }); m_collectionField = new CCombo(wOutputComp, SWT.BORDER); props.setLook(m_collectionField); m_collectionField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_currentMeta.setChanged(); m_collectionField.setToolTipText(transMeta.environmentSubstitute(m_collectionField.getText())); } }); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_dbNameField, margin); fd.right = new FormAttachment(m_getCollectionsBut, -margin); m_collectionField.setLayoutData(fd); // batch insert line Label batchLab = new Label(wOutputComp, SWT.RIGHT); batchLab.setText(getString("MongoDbOutputDialog.BatchInsertSize.Label")); //$NON-NLS-1$ props.setLook(batchLab); batchLab.setToolTipText(getString("MongoDbOutputDialog.BatchInsertSize.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_collectionField, margin); fd.right = new FormAttachment(middle, -margin); batchLab.setLayoutData(fd); m_batchInsertSizeField = new TextVar(transMeta, wOutputComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_batchInsertSizeField); m_batchInsertSizeField.addModifyListener(lsMod); // set the tool tip to the contents with any env variables expanded m_batchInsertSizeField.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_batchInsertSizeField .setToolTipText(transMeta.environmentSubstitute(m_batchInsertSizeField.getText())); } }); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_collectionField, margin); fd.left = new FormAttachment(middle, 0); m_batchInsertSizeField.setLayoutData(fd); // truncate line Label truncateLab = new Label(wOutputComp, SWT.RIGHT); truncateLab.setText(getString("MongoDbOutputDialog.Truncate.Label")); //$NON-NLS-1$ props.setLook(truncateLab); truncateLab.setToolTipText(getString("MongoDbOutputDialog.Truncate.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_batchInsertSizeField, margin); fd.right = new FormAttachment(middle, -margin); truncateLab.setLayoutData(fd); m_truncateBut = new Button(wOutputComp, SWT.CHECK); props.setLook(m_truncateBut); m_truncateBut.setToolTipText(getString("MongoDbOutputDialog.Truncate.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_batchInsertSizeField, margin); fd.left = new FormAttachment(middle, 0); m_truncateBut.setLayoutData(fd); m_truncateBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_currentMeta.setChanged(); } }); // update line Label updateLab = new Label(wOutputComp, SWT.RIGHT); updateLab.setText(getString("MongoDbOutputDialog.Update.Label")); //$NON-NLS-1$ props.setLook(updateLab); updateLab.setToolTipText(getString("MongoDbOutputDialog.Update.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_truncateBut, margin); fd.right = new FormAttachment(middle, -margin); updateLab.setLayoutData(fd); m_updateBut = new Button(wOutputComp, SWT.CHECK); m_updateBut = new Button(wOutputComp, SWT.CHECK); props.setLook(m_updateBut); m_updateBut.setToolTipText(getString("MongoDbOutputDialog.Update.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_truncateBut, margin); fd.left = new FormAttachment(middle, 0); m_updateBut.setLayoutData(fd); // multi update can only be used when the update document // contains modifier operations: // http://docs.mongodb.org/manual/reference/method/db.collection.update/#multi-parameter m_updateBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_currentMeta.setChanged(); m_upsertBut.setEnabled(m_updateBut.getSelection()); m_modifierUpdateBut.setEnabled(m_updateBut.getSelection()); m_readPreference.setEnabled(m_modifierUpdateBut.getEnabled() && m_modifierUpdateBut.getSelection()); m_multiBut.setEnabled(m_updateBut.getSelection()); if (!m_updateBut.getSelection()) { m_modifierUpdateBut.setSelection(false); m_multiBut.setSelection(false); m_upsertBut.setSelection(false); } m_multiBut.setEnabled(m_modifierUpdateBut.getSelection()); if (!m_multiBut.getEnabled()) { m_multiBut.setSelection(false); } } }); // upsert line Label upsertLab = new Label(wOutputComp, SWT.RIGHT); upsertLab.setText(getString("MongoDbOutputDialog.Upsert.Label")); //$NON-NLS-1$ props.setLook(upsertLab); upsertLab.setToolTipText(getString("MongoDbOutputDialog.Upsert.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_updateBut, margin); fd.right = new FormAttachment(middle, -margin); upsertLab.setLayoutData(fd); m_upsertBut = new Button(wOutputComp, SWT.CHECK); props.setLook(m_upsertBut); m_upsertBut.setToolTipText(getString("MongoDbOutputDialog.Upsert.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_updateBut, margin); fd.left = new FormAttachment(middle, 0); m_upsertBut.setLayoutData(fd); // multi line Label multiLab = new Label(wOutputComp, SWT.RIGHT); multiLab.setText(getString("MongoDbOutputDialog.Multi.Label")); //$NON-NLS-1$ props.setLook(multiLab); multiLab.setToolTipText(getString("MongoDbOutputDialog.Multi.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_upsertBut, margin); fd.right = new FormAttachment(middle, -margin); multiLab.setLayoutData(fd); m_multiBut = new Button(wOutputComp, SWT.CHECK); props.setLook(m_multiBut); m_multiBut.setToolTipText(getString("MongoDbOutputDialog.Multi.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_upsertBut, margin); fd.left = new FormAttachment(middle, 0); m_multiBut.setLayoutData(fd); m_multiBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_currentMeta.setChanged(); } }); // modifier update Label modifierLab = new Label(wOutputComp, SWT.RIGHT); modifierLab.setText(getString("MongoDbOutputDialog.Modifier.Label")); //$NON-NLS-1$ props.setLook(modifierLab); modifierLab.setToolTipText(getString("MongoDbOutputDialog.Modifier.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_multiBut, margin); fd.right = new FormAttachment(middle, -margin); modifierLab.setLayoutData(fd); m_modifierUpdateBut = new Button(wOutputComp, SWT.CHECK); props.setLook(m_modifierUpdateBut); m_modifierUpdateBut.setToolTipText(getString("MongoDbOutputDialog.Modifier.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_multiBut, margin); fd.left = new FormAttachment(middle, 0); m_modifierUpdateBut.setLayoutData(fd); m_modifierUpdateBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_currentMeta.setChanged(); m_multiBut.setEnabled(m_modifierUpdateBut.getSelection()); if (!m_modifierUpdateBut.getSelection()) { m_multiBut.setSelection(false); } m_readPreference.setEnabled(m_modifierUpdateBut.getEnabled() && m_modifierUpdateBut.getSelection()); } }); // write concern Label writeConcernLab = new Label(wOutputComp, SWT.RIGHT); writeConcernLab.setText(getString("MongoDbOutputDialog.WriteConcern.Label")); //$NON-NLS-1$ writeConcernLab.setToolTipText(getString("MongoDbOutputDialog.WriteConcern.TipText")); //$NON-NLS-1$ props.setLook(writeConcernLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_modifierUpdateBut, margin); fd.right = new FormAttachment(middle, -margin); writeConcernLab.setLayoutData(fd); Button getCustomWCBut = new Button(wOutputComp, SWT.PUSH | SWT.CENTER); props.setLook(getCustomWCBut); getCustomWCBut.setText(getString("MongoDbOutputDialog.WriteConcern.CustomWriteConcerns")); //$NON-NLS-1$ fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_modifierUpdateBut, 0); getCustomWCBut.setLayoutData(fd); getCustomWCBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setupCustomWriteConcernNames(); } }); m_writeConcern = new CCombo(wOutputComp, SWT.BORDER); props.setLook(m_writeConcern); m_writeConcern.addModifyListener(lsMod); fd = new FormData(); fd.right = new FormAttachment(getCustomWCBut, 0); fd.top = new FormAttachment(m_modifierUpdateBut, margin); fd.left = new FormAttachment(middle, 0); m_writeConcern.setLayoutData(fd); // wTimeout Label wTimeoutLab = new Label(wOutputComp, SWT.RIGHT); wTimeoutLab.setText(getString("MongoDbOutputDialog.WTimeout.Label")); //$NON-NLS-1$ wTimeoutLab.setToolTipText(getString("MongoDbOutputDialog.WTimeout.TipText")); //$NON-NLS-1$ props.setLook(wTimeoutLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_writeConcern, margin); fd.right = new FormAttachment(middle, -margin); wTimeoutLab.setLayoutData(fd); m_wTimeout = new TextVar(transMeta, wOutputComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_wTimeout); m_wTimeout.addModifyListener(lsMod); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_writeConcern, margin); fd.left = new FormAttachment(middle, 0); m_wTimeout.setLayoutData(fd); m_wTimeout.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_wTimeout.setToolTipText(transMeta.environmentSubstitute(m_wTimeout.getText())); } }); Label journalWritesLab = new Label(wOutputComp, SWT.RIGHT); journalWritesLab.setText(getString("MongoDbOutputDialog.JournalWrites.Label")); //$NON-NLS-1$ journalWritesLab.setToolTipText(getString("MongoDbOutputDialog.JournalWrites.TipText")); //$NON-NLS-1$ props.setLook(journalWritesLab); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_wTimeout, margin); fd.right = new FormAttachment(middle, -margin); journalWritesLab.setLayoutData(fd); m_journalWritesCheck = new Button(wOutputComp, SWT.CHECK); props.setLook(m_journalWritesCheck); m_journalWritesCheck.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { m_currentMeta.setChanged(); } }); fd = new FormData(); fd.right = new FormAttachment(100, 0); fd.top = new FormAttachment(m_wTimeout, margin); fd.left = new FormAttachment(middle, 0); m_journalWritesCheck.setLayoutData(fd); // read preference Label readPrefL = new Label(wOutputComp, SWT.RIGHT); readPrefL.setText(getString("MongoDbOutputDialog.ReadPreferenceLabel")); //$NON-NLS-1$ readPrefL.setToolTipText(getString("MongoDbOutputDialog.ReadPreferenceLabel.TipText")); //$NON-NLS-1$ props.setLook(readPrefL); fd = new FormData(); fd.left = new FormAttachment(0, -margin); fd.top = new FormAttachment(m_journalWritesCheck, margin); fd.right = new FormAttachment(middle, -margin); readPrefL.setLayoutData(fd); m_readPreference = new CCombo(wOutputComp, SWT.BORDER); props.setLook(m_readPreference); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_journalWritesCheck, margin); fd.right = new FormAttachment(100, 0); m_readPreference.setLayoutData(fd); m_readPreference.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_currentMeta.setChanged(); m_readPreference.setToolTipText(transMeta.environmentSubstitute(m_readPreference.getText())); } }); m_readPreference.add(NamedReadPreference.PRIMARY.getName()); m_readPreference.add(NamedReadPreference.PRIMARY_PREFERRED.getName()); m_readPreference.add(NamedReadPreference.SECONDARY.getName()); m_readPreference.add(NamedReadPreference.SECONDARY_PREFERRED.getName()); m_readPreference.add(NamedReadPreference.NEAREST.getName()); // retries stuff Label retriesLab = new Label(wOutputComp, SWT.RIGHT); props.setLook(retriesLab); retriesLab.setText(getString("MongoDbOutputDialog.WriteRetries.Label")); //$NON-NLS-1$ retriesLab.setToolTipText(getString("MongoDbOutputDialog.WriteRetries.TipText")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, -margin); fd.top = new FormAttachment(m_readPreference, margin); fd.right = new FormAttachment(middle, -margin); retriesLab.setLayoutData(fd); m_writeRetries = new TextVar(transMeta, wOutputComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_writeRetries); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_readPreference, margin); fd.right = new FormAttachment(100, 0); m_writeRetries.setLayoutData(fd); m_writeRetries.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { m_writeRetries.setToolTipText(transMeta.environmentSubstitute(m_writeRetries.getText())); } }); Label retriesDelayLab = new Label(wOutputComp, SWT.RIGHT); props.setLook(retriesDelayLab); retriesDelayLab.setText(getString("MongoDbOutputDialog.WriteRetriesDelay.Label")); //$NON-NLS-1$ fd = new FormData(); fd.left = new FormAttachment(0, -margin); fd.top = new FormAttachment(m_writeRetries, margin); fd.right = new FormAttachment(middle, -margin); retriesDelayLab.setLayoutData(fd); m_writeRetryDelay = new TextVar(transMeta, wOutputComp, SWT.SINGLE | SWT.LEFT | SWT.BORDER); props.setLook(m_writeRetryDelay); fd = new FormData(); fd.left = new FormAttachment(middle, 0); fd.top = new FormAttachment(m_writeRetries, margin); fd.right = new FormAttachment(100, 0); m_writeRetryDelay.setLayoutData(fd); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, 0); wOutputComp.setLayoutData(fd); wOutputComp.layout(); m_wOutputOptionsTab.setControl(wOutputComp); // --- start of the fields tab m_wMongoFieldsTab = new CTabItem(m_wTabFolder, SWT.NONE); m_wMongoFieldsTab.setText(getString("MongoDbOutputDialog.FieldsTab.TabTitle")); //$NON-NLS-1$ Composite wFieldsComp = new Composite(m_wTabFolder, SWT.NONE); props.setLook(wFieldsComp); FormLayout filterLayout = new FormLayout(); filterLayout.marginWidth = 3; filterLayout.marginHeight = 3; wFieldsComp.setLayout(filterLayout); final ColumnInfo[] colInf = new ColumnInfo[] { new ColumnInfo(getString("MongoDbOutputDialog.Fields.Incoming"), ColumnInfo.COLUMN_TYPE_TEXT, false), new ColumnInfo(getString("MongoDbOutputDialog.Fields.Path"), ColumnInfo.COLUMN_TYPE_TEXT, false), createReadOnlyComboBox("MongoDbOutputDialog.Fields.UseIncomingName", "Y", "N"), createReadOnlyComboBox("MongoDbOutputDialog.Fields.NullValues", getString("MongoDbOutputDialog.Fields.NullValues.Insert"), getString("MongoDbOutputDialog.Fields.NullValues.Ignore")), createReadOnlyComboBox("MongoDbOutputDialog.Fields.JSON", "Y", "N"), createReadOnlyComboBox("MongoDbOutputDialog.Fields.UpdateMatchField", "Y", "N"), createReadOnlyComboBox("MongoDbOutputDialog.Fields.ModifierUpdateOperation", "N/A", "$set", "$inc", "$push"), createReadOnlyComboBox("MongoDbOutputDialog.Fields.ModifierApplyPolicy", "Insert&Update", "Insert", "Update") }; // get fields but m_getFieldsBut = new Button(wFieldsComp, SWT.PUSH | SWT.CENTER); props.setLook(m_getFieldsBut); m_getFieldsBut.setText(getString("MongoDbOutputDialog.GetFieldsBut")); //$NON-NLS-1$ fd = new FormData(); // fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, -margin * 2); fd.left = new FormAttachment(0, margin); m_getFieldsBut.setLayoutData(fd); m_getFieldsBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { getFields(); } }); m_previewDocStructBut = new Button(wFieldsComp, SWT.PUSH | SWT.CENTER); props.setLook(m_previewDocStructBut); m_previewDocStructBut.setText(getString("MongoDbOutputDialog.PreviewDocStructBut")); //$NON-NLS-1$ fd = new FormData(); // fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, -margin * 2); fd.left = new FormAttachment(m_getFieldsBut, margin); m_previewDocStructBut.setLayoutData(fd); m_previewDocStructBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { previewDocStruct(); } }); m_mongoFieldsView = new TableView(transMeta, wFieldsComp, SWT.FULL_SELECTION | SWT.MULTI, colInf, 1, lsMod, props); fd = new FormData(); fd.top = new FormAttachment(0, margin * 2); fd.bottom = new FormAttachment(m_getFieldsBut, -margin * 2); fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); m_mongoFieldsView.setLayoutData(fd); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, 0); wFieldsComp.setLayoutData(fd); wFieldsComp.layout(); m_wMongoFieldsTab.setControl(wFieldsComp); // indexes tab ------------------ m_wMongoIndexesTab = new CTabItem(m_wTabFolder, SWT.NONE); m_wMongoIndexesTab.setText(getString("MongoDbOutputDialog.IndexesTab.TabTitle")); //$NON-NLS-1$ Composite wIndexesComp = new Composite(m_wTabFolder, SWT.NONE); props.setLook(wIndexesComp); FormLayout indexesLayout = new FormLayout(); indexesLayout.marginWidth = 3; indexesLayout.marginHeight = 3; wIndexesComp.setLayout(indexesLayout); final ColumnInfo[] colInf2 = new ColumnInfo[] { new ColumnInfo(getString("MongoDbOutputDialog.Indexes.IndexFields"), //$NON-NLS-1$ ColumnInfo.COLUMN_TYPE_TEXT, false), new ColumnInfo(getString("MongoDbOutputDialog.Indexes.IndexOpp"), //$NON-NLS-1$ ColumnInfo.COLUMN_TYPE_CCOMBO, false), new ColumnInfo(getString("MongoDbOutputDialog.Indexes.Unique"), //$NON-NLS-1$ ColumnInfo.COLUMN_TYPE_CCOMBO, false), new ColumnInfo(getString("MongoDbOutputDialog.Indexes.Sparse"), //$NON-NLS-1$ ColumnInfo.COLUMN_TYPE_CCOMBO, false), }; colInf2[1].setComboValues(new String[] { "Create", "Drop" }); //$NON-NLS-1$ //$NON-NLS-2$ colInf2[1].setReadOnly(true); colInf2[2].setComboValues(new String[] { "Y", "N" }); //$NON-NLS-1$ //$NON-NLS-2$ colInf2[2].setReadOnly(true); colInf2[3].setComboValues(new String[] { "Y", "N" }); //$NON-NLS-1$ //$NON-NLS-2$ colInf2[3].setReadOnly(true); // get indexes but m_showIndexesBut = new Button(wIndexesComp, SWT.PUSH | SWT.CENTER); props.setLook(m_showIndexesBut); m_showIndexesBut.setText(getString("MongoDbOutputDialog.ShowIndexesBut")); //$NON-NLS-1$ fd = new FormData(); fd.bottom = new FormAttachment(100, -margin * 2); fd.left = new FormAttachment(0, margin); m_showIndexesBut.setLayoutData(fd); m_showIndexesBut.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { showIndexInfo(); } }); m_mongoIndexesView = new TableView(transMeta, wIndexesComp, SWT.FULL_SELECTION | SWT.MULTI, colInf2, 1, lsMod, props); fd = new FormData(); fd.top = new FormAttachment(0, margin * 2); fd.bottom = new FormAttachment(m_showIndexesBut, -margin * 2); fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); m_mongoIndexesView.setLayoutData(fd); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, 0); wIndexesComp.setLayoutData(fd); wIndexesComp.layout(); m_wMongoIndexesTab.setControl(wIndexesComp); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.top = new FormAttachment(m_stepnameText, margin); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, -50); m_wTabFolder.setLayoutData(fd); // Buttons inherited from BaseStepDialog wOK = new Button(shell, SWT.PUSH); wOK.setText(getString("System.Button.OK")); //$NON-NLS-1$ wCancel = new Button(shell, SWT.PUSH); wCancel.setText(getString("System.Button.Cancel")); //$NON-NLS-1$ setButtonPositions(new Button[] { wOK, wCancel }, margin, m_wTabFolder); // Add listeners lsCancel = new Listener() { @Override public void handleEvent(Event e) { cancel(); } }; lsOK = new Listener() { @Override public void handleEvent(Event e) { ok(); } }; wCancel.addListener(SWT.Selection, lsCancel); wOK.addListener(SWT.Selection, lsOK); lsDef = new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { ok(); } }; m_stepnameText.addSelectionListener(lsDef); // Detect X or ALT-F4 or something that kills this window... shell.addShellListener(new ShellAdapter() { @Override public void shellClosed(ShellEvent e) { cancel(); } }); m_wTabFolder.setSelection(0); setSize(); getData(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } return stepname; } private ColumnInfo createReadOnlyComboBox(String i18nKey, String... values) { ColumnInfo info = new ColumnInfo(getString(i18nKey), ColumnInfo.COLUMN_TYPE_CCOMBO, false); info.setReadOnly(true); info.setComboValues(values); return info; } protected void cancel() { stepname = null; m_currentMeta.setChanged(changed); dispose(); } private void ok() { if (Const.isEmpty(m_stepnameText.getText())) { return; } stepname = m_stepnameText.getText(); getInfo(m_currentMeta); if (m_currentMeta.getMongoFields() == null) { // popup dialog warning that no paths have been defined ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_WARNING | SWT.OK, getString("MongoDbOutputDialog.ErrorMessage.NoFieldPathsDefined.Title"), getString("MongoDbOutputDialog.ErrorMessage.NoFieldPathsDefined")); //$NON-NLS-1$ smd.open(); } if (!m_originalMeta.equals(m_currentMeta)) { m_currentMeta.setChanged(); changed = m_currentMeta.hasChanged(); } dispose(); } private void getInfo(MongoDbOutputMeta meta) { meta.setHostnames(m_hostnameField.getText()); meta.setPort(m_portField.getText()); meta.setUseAllReplicaSetMembers(m_useAllReplicaSetMembersBut.getSelection()); meta.setAuthenticationDatabaseName(m_authDbName.getText()); meta.setAuthenticationUser(m_usernameField.getText()); meta.setAuthenticationPassword(m_passField.getText()); meta.setUseKerberosAuthentication(m_kerberosBut.getSelection()); meta.setDbName(m_dbNameField.getText()); meta.setCollection(m_collectionField.getText()); meta.setBatchInsertSize(m_batchInsertSizeField.getText()); meta.setUpdate(m_updateBut.getSelection()); meta.setUpsert(m_upsertBut.getSelection()); meta.setMulti(m_multiBut.getSelection()); meta.setTruncate(m_truncateBut.getSelection()); meta.setModifierUpdate(m_modifierUpdateBut.getSelection()); meta.setConnectTimeout(m_connectTimeout.getText()); meta.setSocketTimeout(m_socketTimeout.getText()); meta.setWriteConcern(m_writeConcern.getText()); meta.setWTimeout(m_wTimeout.getText()); meta.setJournal(m_journalWritesCheck.getSelection()); meta.setReadPreference(m_readPreference.getText()); meta.setWriteRetries(m_writeRetries.getText()); meta.setWriteRetryDelay(m_writeRetryDelay.getText()); meta.setMongoFields(tableToMongoFieldList()); // indexes int numNonEmpty = m_mongoIndexesView.nrNonEmpty(); List<MongoDbOutputMeta.MongoIndex> mongoIndexes = new ArrayList<MongoDbOutputMeta.MongoIndex>(); if (numNonEmpty > 0) { for (int i = 0; i < numNonEmpty; i++) { TableItem item = m_mongoIndexesView.getNonEmpty(i); String indexFieldList = item.getText(1).trim(); String indexOpp = item.getText(2).trim(); String unique = item.getText(3).trim(); String sparse = item.getText(4).trim(); MongoDbOutputMeta.MongoIndex newIndex = new MongoDbOutputMeta.MongoIndex(); newIndex.m_pathToFields = indexFieldList; newIndex.m_drop = indexOpp.equals("Drop"); //$NON-NLS-1$ newIndex.m_unique = unique.equals("Y"); //$NON-NLS-1$ newIndex.m_sparse = sparse.equals("Y"); //$NON-NLS-1$ mongoIndexes.add(newIndex); } } meta.setMongoIndexes(mongoIndexes); } private List<MongoDbOutputMeta.MongoField> tableToMongoFieldList() { int numNonEmpty = m_mongoFieldsView.nrNonEmpty(); if (numNonEmpty > 0) { List<MongoDbOutputMeta.MongoField> mongoFields = new ArrayList<MongoDbOutputMeta.MongoField>( numNonEmpty); for (int i = 0; i < numNonEmpty; i++) { TableItem item = m_mongoFieldsView.getNonEmpty(i); String incoming = item.getText(1).trim(); String path = item.getText(2).trim(); String useIncoming = item.getText(3).trim(); String allowNull = item.getText(4).trim(); String json = item.getText(5).trim(); String updateMatch = item.getText(6).trim(); String modifierOp = item.getText(7).trim(); String modifierPolicy = item.getText(8).trim(); MongoDbOutputMeta.MongoField newField = new MongoDbOutputMeta.MongoField(); newField.m_incomingFieldName = incoming; newField.m_mongoDocPath = path; newField.m_useIncomingFieldNameAsMongoFieldName = ((useIncoming.length() > 0) ? useIncoming.equals("Y") //$NON-NLS-1$ : true); newField.insertNull = getString("MongoDbOutputDialog.Fields.NullValues.Insert").equals(allowNull); newField.m_JSON = ((json.length() > 0) ? json.equals("Y") : false); //$NON-NLS-1$ newField.m_updateMatchField = (updateMatch.equals("Y")); //$NON-NLS-1$ if (modifierOp.length() == 0) { newField.m_modifierUpdateOperation = "N/A"; //$NON-NLS-1$ } else { newField.m_modifierUpdateOperation = modifierOp; } newField.m_modifierOperationApplyPolicy = modifierPolicy; mongoFields.add(newField); } return mongoFields; } return null; } private void getData() { m_hostnameField.setText(Const.NVL(m_currentMeta.getHostnames(), "")); //$NON-NLS-1$ m_portField.setText(Const.NVL(m_currentMeta.getPort(), "")); //$NON-NLS-1$ m_useAllReplicaSetMembersBut.setSelection(m_currentMeta.getUseAllReplicaSetMembers()); m_authDbName.setText(Const.NVL(m_currentMeta.getAuthenticationDatabaseName(), "")); //$NON-NLS-1$ m_usernameField.setText(Const.NVL(m_currentMeta.getAuthenticationUser(), "")); //$NON-NLS-1$ m_passField.setText(Const.NVL(m_currentMeta.getAuthenticationPassword(), "")); //$NON-NLS-1$ m_kerberosBut.setSelection(m_currentMeta.getUseKerberosAuthentication()); m_passField.setEnabled(!m_kerberosBut.getSelection()); m_dbNameField.setText(Const.NVL(m_currentMeta.getDbName(), "")); //$NON-NLS-1$ m_collectionField.setText(Const.NVL(m_currentMeta.getCollection(), "")); //$NON-NLS-1$ m_batchInsertSizeField.setText(Const.NVL(m_currentMeta.getBatchInsertSize(), "")); //$NON-NLS-1$ m_updateBut.setSelection(m_currentMeta.getUpdate()); m_upsertBut.setSelection(m_currentMeta.getUpsert()); m_multiBut.setSelection(m_currentMeta.getMulti()); m_truncateBut.setSelection(m_currentMeta.getTruncate()); m_modifierUpdateBut.setSelection(m_currentMeta.getModifierUpdate()); m_upsertBut.setEnabled(m_updateBut.getSelection()); m_modifierUpdateBut.setEnabled(m_updateBut.getSelection()); m_multiBut.setEnabled(m_updateBut.getSelection()); if (!m_updateBut.getSelection()) { m_modifierUpdateBut.setSelection(false); m_multiBut.setSelection(false); } m_multiBut.setEnabled(m_modifierUpdateBut.getSelection()); if (!m_multiBut.getEnabled()) { m_multiBut.setSelection(false); } m_readPreference.setEnabled(m_modifierUpdateBut.getEnabled() && m_modifierUpdateBut.getSelection()); m_connectTimeout.setText(Const.NVL(m_currentMeta.getConnectTimeout(), "")); //$NON-NLS-1$ m_socketTimeout.setText(Const.NVL(m_currentMeta.getSocketTimeout(), "")); //$NON-NLS-1$ m_writeConcern.setText(Const.NVL(m_currentMeta.getWriteConcern(), "")); //$NON-NLS-1$ m_wTimeout.setText(Const.NVL(m_currentMeta.getWTimeout(), "")); //$NON-NLS-1$ m_journalWritesCheck.setSelection(m_currentMeta.getJournal()); m_readPreference.setText(Const.NVL(m_currentMeta.getReadPreference(), "")); //$NON-NLS-1$ m_writeRetries.setText(Const.NVL(m_currentMeta.getWriteRetries(), "" //$NON-NLS-1$ + MongoDbOutputMeta.RETRIES)); m_writeRetryDelay.setText(Const.NVL(m_currentMeta.getWriteRetryDelay(), "" //$NON-NLS-1$ + MongoDbOutputMeta.RETRIES)); List<MongoDbOutputMeta.MongoField> mongoFields = m_currentMeta.getMongoFields(); if (mongoFields != null && mongoFields.size() > 0) { for (MongoDbOutputMeta.MongoField field : mongoFields) { TableItem item = new TableItem(m_mongoFieldsView.table, SWT.NONE); item.setText(1, Const.NVL(field.m_incomingFieldName, "")); //$NON-NLS-1$ item.setText(2, Const.NVL(field.m_mongoDocPath, "")); //$NON-NLS-1$ item.setText(3, field.m_useIncomingFieldNameAsMongoFieldName ? "Y" : "N"); //$NON-NLS-1$ //$NON-NLS-2$ String insertNullKey = field.insertNull ? "MongoDbOutputDialog.Fields.NullValues.Insert" : "MongoDbOutputDialog.Fields.NullValues.Ignore"; item.setText(4, getString(insertNullKey)); item.setText(5, field.m_JSON ? "Y" : "N"); //$NON-NLS-1$ //$NON-NLS-2$ item.setText(6, field.m_updateMatchField ? "Y" : "N"); //$NON-NLS-1$ //$NON-NLS-2$ item.setText(7, Const.NVL(field.m_modifierUpdateOperation, "")); //$NON-NLS-1$ item.setText(8, Const.NVL(field.m_modifierOperationApplyPolicy, "")); //$NON-NLS-1$ } m_mongoFieldsView.removeEmptyRows(); m_mongoFieldsView.setRowNums(); m_mongoFieldsView.optWidth(true); } List<MongoDbOutputMeta.MongoIndex> mongoIndexes = m_currentMeta.getMongoIndexes(); if (mongoIndexes != null && mongoIndexes.size() > 0) { for (MongoDbOutputMeta.MongoIndex index : mongoIndexes) { TableItem item = new TableItem(m_mongoIndexesView.table, SWT.None); item.setText(1, Const.NVL(index.m_pathToFields, "")); //$NON-NLS-1$ if (index.m_drop) { item.setText(2, "Drop"); //$NON-NLS-1$ } else { item.setText(2, "Create"); //$NON-NLS-1$ } item.setText(3, Const.NVL(index.m_unique ? "Y" : "N", "N")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ item.setText(4, Const.NVL(index.m_sparse ? "Y" : "N", "N")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } m_mongoIndexesView.removeEmptyRows(); m_mongoIndexesView.setRowNums(); m_mongoIndexesView.optWidth(true); } } private void setupCollectionNamesForDB(boolean quiet) { final String hostname = transMeta.environmentSubstitute(m_hostnameField.getText()); final String dB = transMeta.environmentSubstitute(m_dbNameField.getText()); String current = m_collectionField.getText(); m_collectionField.removeAll(); if (!Const.isEmpty(hostname) && !Const.isEmpty(dB)) { final MongoDbOutputMeta meta = new MongoDbOutputMeta(); getInfo(meta); try { MongoClientWrapper clientWrapper = MongoWrapperUtil.createMongoClientWrapper(meta, transMeta, log); Set<String> collections = new HashSet<String>(); try { collections = clientWrapper.getCollectionsNames(dB); } finally { clientWrapper.dispose(); } for (String c : collections) { m_collectionField.add(c); } } catch (Exception e) { // Unwrap the PrivilegedActionException if it was thrown if (e instanceof PrivilegedActionException) { e = ((PrivilegedActionException) e).getException(); } logError(getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ new ErrorDialog(shell, getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), //$NON-NLS-1$ //$NON-NLS-2$ getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ } } else { // popup some feedback String missingConnDetails = ""; //$NON-NLS-1$ if (Const.isEmpty(hostname)) { missingConnDetails += "host name(s)"; //$NON-NLS-1$ } if (Const.isEmpty(dB)) { missingConnDetails += " database"; //$NON-NLS-1$ } ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_WARNING | SWT.OK, getString("MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails.Title"), BaseMessages.getString(PKG, //$NON-NLS-1$ "MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails", missingConnDetails)); //$NON-NLS-1$ smd.open(); } if (!Const.isEmpty(current)) { m_collectionField.setText(current); } } private void setupCustomWriteConcernNames() { String hostname = transMeta.environmentSubstitute(m_hostnameField.getText()); if (!Const.isEmpty(hostname)) { MongoDbOutputMeta meta = new MongoDbOutputMeta(); getInfo(meta); try { MongoClientWrapper wrapper = MongoWrapperUtil.createMongoClientWrapper(meta, transMeta, log); List<String> custom = new ArrayList<String>(); try { custom = wrapper.getLastErrorModes(); } finally { wrapper.dispose(); } if (custom.size() > 0) { String current = m_writeConcern.getText(); m_writeConcern.removeAll(); for (String s : custom) { m_writeConcern.add(s); } if (!Const.isEmpty(current)) { m_writeConcern.setText(current); } } } catch (Exception e) { logError(getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ new ErrorDialog(shell, getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), //$NON-NLS-1$ //$NON-NLS-2$ getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ } } else { ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_WARNING | SWT.OK, getString("MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails.Title"), BaseMessages.getString(PKG, //$NON-NLS-1$ "MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails", "host name(s)")); //$NON-NLS-2$ //$NON-NLS-2$ smd.open(); } } private void setupDBNames() { String current = m_dbNameField.getText(); m_dbNameField.removeAll(); String hostname = transMeta.environmentSubstitute(m_hostnameField.getText()); if (!Const.isEmpty(hostname)) { try { final MongoDbOutputMeta meta = new MongoDbOutputMeta(); getInfo(meta); List<String> dbNames = new ArrayList<String>(); MongoClientWrapper wrapper = MongoWrapperUtil.createMongoClientWrapper(meta, transMeta, log); try { dbNames = wrapper.getDatabaseNames(); } finally { wrapper.dispose(); } for (String s : dbNames) { m_dbNameField.add(s); } } catch (Exception e) { logError(getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ new ErrorDialog(shell, getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), //$NON-NLS-1$ //$NON-NLS-2$ getString("MongoDbOutputDialog.ErrorMessage.UnableToConnect"), e); //$NON-NLS-1$ } } else { // popup some feedback ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_WARNING | SWT.OK, getString("MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails.Title"), BaseMessages.getString(PKG, //$NON-NLS-1$ "MongoDbOutputDialog.ErrorMessage.MissingConnectionDetails", "host name(s)")); //$NON-NLS-2$ //$NON-NLS-2$ smd.open(); } if (!Const.isEmpty(current)) { m_dbNameField.setText(current); } } private void getFields() { try { RowMetaInterface r = transMeta.getPrevStepFields(stepname); if (r != null) { BaseStepDialog.getFieldsFromPrevious(r, m_mongoFieldsView, 1, new int[] { 1 }, null, -1, -1, null); } } catch (KettleException e) { logError(getString("System.Dialog.GetFieldsFailed.Message"), //$NON-NLS-1$ e); new ErrorDialog(shell, getString("System.Dialog.GetFieldsFailed.Title"), getString("System.Dialog.GetFieldsFailed.Message"), e); //$NON-NLS-1$ } } private static enum Element { OPEN_BRACE, CLOSE_BRACE, OPEN_BRACKET, CLOSE_BRACKET, COMMA } private static void pad(StringBuffer toPad, int numBlanks) { for (int i = 0; i < numBlanks; i++) { toPad.append(' '); } } /** * Format JSON document structure for printing to the preview dialog * * @param toFormat the document to format * @return a String containing the formatted document structure */ public static String prettyPrintDocStructure(String toFormat) { StringBuffer result = new StringBuffer(); int indent = 0; String source = toFormat.replaceAll("[ ]*,", ","); //$NON-NLS-1$ //$NON-NLS-2$ Element next = Element.OPEN_BRACE; while (source.length() > 0) { source = source.trim(); String toIndent = ""; //$NON-NLS-1$ int minIndex = Integer.MAX_VALUE; char targetChar = '{'; if (source.indexOf('{') > -1 && source.indexOf('{') < minIndex) { next = Element.OPEN_BRACE; minIndex = source.indexOf('{'); targetChar = '{'; } if (source.indexOf('}') > -1 && source.indexOf('}') < minIndex) { next = Element.CLOSE_BRACE; minIndex = source.indexOf('}'); targetChar = '}'; } if (source.indexOf('[') > -1 && source.indexOf('[') < minIndex) { next = Element.OPEN_BRACKET; minIndex = source.indexOf('['); targetChar = '['; } if (source.indexOf(']') > -1 && source.indexOf(']') < minIndex) { next = Element.CLOSE_BRACKET; minIndex = source.indexOf(']'); targetChar = ']'; } if (source.indexOf(',') > -1 && source.indexOf(',') < minIndex) { next = Element.COMMA; minIndex = source.indexOf(','); targetChar = ','; } if (minIndex == 0) { if (next == Element.CLOSE_BRACE || next == Element.CLOSE_BRACKET) { indent -= 2; } pad(result, indent); String comma = ""; //$NON-NLS-1$ int offset = 1; if (source.length() >= 2 && source.charAt(1) == ',') { comma = ","; //$NON-NLS-1$ offset = 2; } result.append(targetChar).append(comma).append("\n"); //$NON-NLS-1$ source = source.substring(offset, source.length()); } else { pad(result, indent); if (next == Element.CLOSE_BRACE || next == Element.CLOSE_BRACKET) { toIndent = source.substring(0, minIndex); source = source.substring(minIndex, source.length()); } else { toIndent = source.substring(0, minIndex + 1); source = source.substring(minIndex + 1, source.length()); } result.append(toIndent.trim()).append("\n"); //$NON-NLS-1$ } if (next == Element.OPEN_BRACE || next == Element.OPEN_BRACKET) { indent += 2; } } return result.toString(); } private void previewDocStruct() { List<MongoDbOutputMeta.MongoField> mongoFields = tableToMongoFieldList(); if (mongoFields == null || mongoFields.size() == 0) { return; } // Try and get meta data on incoming fields RowMetaInterface actualR = null; RowMetaInterface r; boolean gotGenuineRowMeta = false; try { actualR = transMeta.getPrevStepFields(stepname); gotGenuineRowMeta = true; } catch (KettleException e) { // don't complain if we can't } r = new RowMeta(); Object[] dummyRow = new Object[mongoFields.size()]; int i = 0; try { boolean hasTopLevelJSONDocInsert = MongoDbOutputData.scanForInsertTopLevelJSONDoc(mongoFields); for (MongoDbOutputMeta.MongoField field : mongoFields) { // set up dummy row meta ValueMetaInterface vm = ValueMetaFactory.createValueMeta(ValueMetaInterface.TYPE_STRING); vm.setName(field.m_incomingFieldName); r.addValueMeta(vm); String val = ""; //$NON-NLS-1$ if (gotGenuineRowMeta && actualR.indexOfValue(field.m_incomingFieldName) >= 0) { int index = actualR.indexOfValue(field.m_incomingFieldName); switch (actualR.getValueMeta(index).getType()) { case ValueMetaInterface.TYPE_STRING: if (field.m_JSON) { if (!field.m_useIncomingFieldNameAsMongoFieldName && Const.isEmpty(field.m_mongoDocPath)) { // we will actually have to parse some kind of JSON doc // here in the case where the matching doc/doc to be inserted is // a full top-level incoming JSON doc val = "{\"IncomingJSONDoc\" : \"<document content>\"}"; //$NON-NLS-1$ } else { val = "<JSON sub document>"; //$NON-NLS-1$ // turn this off for the purpose of doc structure // visualization so that we don't screw up for the // lack of a real JSON doc to parse :-) field.m_JSON = false; } } else { val = "<string val>"; //$NON-NLS-1$ } break; case ValueMetaInterface.TYPE_INTEGER: val = "<integer val>"; //$NON-NLS-1$ break; case ValueMetaInterface.TYPE_NUMBER: val = "<number val>"; //$NON-NLS-1$ break; case ValueMetaInterface.TYPE_BOOLEAN: val = "<bool val>"; //$NON-NLS-1$ break; case ValueMetaInterface.TYPE_DATE: val = "<date val>"; //$NON-NLS-1$ break; case ValueMetaInterface.TYPE_BINARY: val = "<binary val>"; //$NON-NLS-1$ break; default: val = "<unsupported value type>"; //$NON-NLS-1$ } } else { val = "<value>"; //$NON-NLS-1$ } dummyRow[i++] = val; } VariableSpace vs = new Variables(); MongoDbOutputData.MongoTopLevel topLevelStruct = MongoDbOutputData.checkTopLevelConsistency(mongoFields, vs); for (MongoDbOutputMeta.MongoField m : mongoFields) { m.m_modifierOperationApplyPolicy = "Insert&Update"; //$NON-NLS-1$ m.init(vs); } String toDisplay = ""; //$NON-NLS-1$ String windowTitle = getString("MongoDbOutputDialog.PreviewDocStructure.Title"); //$NON-NLS-1$ // if (!m_currentMeta.getModifierUpdate()) { if (!m_modifierUpdateBut.getSelection()) { DBObject result = MongoDbOutputData.kettleRowToMongo(mongoFields, r, dummyRow, vs, topLevelStruct, hasTopLevelJSONDocInsert); toDisplay = prettyPrintDocStructure(result.toString()); } else { DBObject query = MongoDbOutputData.getQueryObject(mongoFields, r, dummyRow, vs, topLevelStruct); DBObject modifier = new MongoDbOutputData().getModifierUpdateObject(mongoFields, r, dummyRow, vs, topLevelStruct); toDisplay = getString("MongoDbOutputDialog.PreviewModifierUpdate.Heading1") //$NON-NLS-1$ + ":\n\n" //$NON-NLS-1$ + prettyPrintDocStructure(query.toString()) + getString("MongoDbOutputDialog.PreviewModifierUpdate.Heading2") //$NON-NLS-1$ + ":\n\n" //$NON-NLS-1$ + prettyPrintDocStructure(modifier.toString()); windowTitle = getString("MongoDbOutputDialog.PreviewModifierUpdate.Title"); //$NON-NLS-1$ } ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_INFORMATION | SWT.OK, windowTitle, toDisplay, true); smd.open(); } catch (Exception ex) { logError(getString("MongoDbOutputDialog.ErrorMessage.ProblemPreviewingDocStructure.Message") //$NON-NLS-1$ + ":\n\n" + ex.getMessage(), ex); //$NON-NLS-1$ new ErrorDialog(shell, getString("MongoDbOutputDialog.ErrorMessage.ProblemPreviewingDocStructure.Title"), //$NON-NLS-1$ getString("MongoDbOutputDialog.ErrorMessage.ProblemPreviewingDocStructure.Message") //$NON-NLS-1$ + ":\n\n" + ex.getMessage(), //$NON-NLS-1$ ex); return; } } private void showIndexInfo() { String hostname = transMeta.environmentSubstitute(m_hostnameField.getText()); String dbName = transMeta.environmentSubstitute(m_dbNameField.getText()); String collection = transMeta.environmentSubstitute(m_collectionField.getText()); if (!Const.isEmpty(hostname)) { MongoClient conn = null; try { MongoDbOutputMeta meta = new MongoDbOutputMeta(); getInfo(meta); MongoClientWrapper wrapper = MongoWrapperUtil.createMongoClientWrapper(meta, transMeta, log); StringBuffer result = new StringBuffer(); for (String index : wrapper.getIndexInfo(dbName, collection)) { result.append(index).append("\n\n"); //$NON-NLS-1$ } ShowMessageDialog smd = new ShowMessageDialog(shell, SWT.ICON_INFORMATION | SWT.OK, BaseMessages.getString(PKG, "MongoDbOutputDialog.IndexInfo", collection), result.toString(), true); //$NON-NLS-1$ smd.open(); } catch (Exception e) { logError(getString("MongoDbOutputDialog.ErrorMessage.GeneralError.Message") //$NON-NLS-1$ + ":\n\n" + e.getMessage(), e); //$NON-NLS-1$ new ErrorDialog(shell, getString("MongoDbOutputDialog.ErrorMessage.IndexPreview.Title"), //$NON-NLS-1$ getString("MongoDbOutputDialog.ErrorMessage.GeneralError.Message") //$NON-NLS-1$ + ":\n\n" + e.getMessage(), //$NON-NLS-1$ e); } finally { if (conn != null) { conn.close(); conn = null; } } } } private String getString(String key) { return BaseMessages.getString(PKG, key); } }