Java tutorial
/*! ****************************************************************************** * * Pentaho Community Edition Project: data-refinery-pdi-plugin * * Copyright (C) 2002-2015 by Pentaho : http://www.pentaho.com * * ******************************************************************************* * * 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.ui.trans.steps.annotation; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.RowData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; 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.Text; import org.pentaho.agilebi.modeler.models.annotations.ModelAnnotationGroup; import org.pentaho.agilebi.modeler.models.annotations.ModelAnnotationManager; import org.pentaho.di.core.Const; import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.gui.SpoonFactory; import org.pentaho.di.core.gui.SpoonInterface; import org.pentaho.di.core.plugins.PluginInterface; import org.pentaho.di.core.refinery.publish.util.ObjectUtils; import org.pentaho.di.core.util.StringUtil; import org.pentaho.di.i18n.BaseMessages; import org.pentaho.di.trans.TransMeta; import org.pentaho.di.trans.step.StepDialogInterface; import org.pentaho.di.trans.step.StepMeta; import org.pentaho.di.trans.step.StepMetaInterface; import org.pentaho.di.trans.steps.annotation.ModelAnnotationMeta; import org.pentaho.di.trans.util.TransUtil; import org.pentaho.di.ui.core.gui.GUIResource; import org.pentaho.di.ui.core.widget.ComboVar; import org.pentaho.di.ui.trans.step.BaseStepDialog; import org.pentaho.di.ui.trans.steps.common.ModelAnnotationEvent; import org.pentaho.di.ui.trans.steps.common.ModelAnnotationsTableComposite; import org.pentaho.metastore.api.exceptions.MetaStoreException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Stack; /** * @author Rowell Belen */ public abstract class BaseAnnotationStepDialog extends BaseStepDialog implements StepDialogInterface { protected static Class<?> PKG = ModelAnnotationMeta.class; // for i18n purposes, needed by Translator2!! protected final int margin = Const.MARGIN; protected final int LEFT_MARGIN_OFFSET = 10; protected final int RIGHT_MARGIN_OFFSET = -10; protected final int SHELL_MIN_WIDTH = 900; protected final int SHELL_MIN_HEIGHT = 670; protected StyledText wDescription; protected Button wApply; protected Button wHelp; protected Label wIcon; protected Label wBottomHorizontalSeparator; protected ModelAnnotationMeta input; protected ModifyListener lsMod; protected Listener lsApply; protected Listener lsGroups; protected Listener lsAddGroup; protected Listener lsCopyGroup; protected Listener lsCheckForVariables; protected final Stack<String> markedForDeletion = new Stack<String>(); protected boolean modelAnnotationDirty; protected boolean preventNewOrRename; public BaseAnnotationStepDialog(Shell parent, Object baseStepMeta, TransMeta transMeta, String stepname) { super(parent, (StepMetaInterface) baseStepMeta, transMeta, stepname); input = (ModelAnnotationMeta) baseStepMeta; TransUtil.resetParams(transMeta, transMeta.getLogChannel()); } @Override public String open() { configureShell(); initializeListeners(); createOkCancelButtons(); Control topWidget = createStepNameWidget(); createContent(topWidget); afterOpen(); // Open the dialog shell.open(); // Wait for close while (!shell.isDisposed()) { if (!getParent().getDisplay().readAndDispatch()) { getParent().getDisplay().sleep(); } } return stepname; } protected void configureShell() { shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN); FormLayout shellLayout = new FormLayout(); shellLayout.marginWidth = Const.FORM_MARGIN; shellLayout.marginHeight = Const.FORM_MARGIN; shell.setLayout(shellLayout); props.setLook(shell); setShellImage(shell, input); shell.setText(getDialogTitle()); // set min size of dialog shell.setMinimumSize(SHELL_MIN_WIDTH, SHELL_MIN_HEIGHT); shell.setSize(SHELL_MIN_WIDTH, SHELL_MIN_HEIGHT); } protected void initializeListeners() { lsMod = new ModifyListener() { public void modifyText(ModifyEvent e) { input.setChanged(); } }; lsApply = new Listener() { @Override public void handleEvent(final Event event) { if (applyChanges()) { modelAnnotationDirty = false; wApply.setEnabled(false); } } }; lsOK = new Listener() { public void handleEvent(Event e) { okay(); } }; lsCancel = new Listener() { public void handleEvent(Event e) { cancel(); } }; lsCheckForVariables = new Listener() { @Override public void handleEvent(final Event event) { if (event.keyCode != 13 && event.keyCode != 0) { return; } if (StringUtils.equals(getWGroups().getText(), getTableComposite().getData().getName()) || Const.isEmpty(getWGroups().getText())) { return; // nothing changed or you are likely in the variable pop-up screen } if (StringUtil.isVariable(getWGroups().getText())) { populateTableFromMetastore(false); int idx = getWGroups().getCComboWidget().indexOf(envSub(getWGroups().getText())); if (idx >= 0) { String varName = getWGroups().getText(); getWGroups().getCComboWidget().select(idx); getWGroups().setText(varName); } setAnnotationsEditEnabled(false); modelAnnotationDirty = false; } else { handleNewOrRenameGroups(); } } }; lsGroups = new Listener() { @Override public void handleEvent(final Event event) { // need to detect if existing model changed, show warning if it does if (checkDirtyGroupDiscard()) { populateTableFromMetastore(); } getWGroups().setEditable(false); } }; lsAddGroup = new Listener() { @Override public void handleEvent(final Event event) { if (checkDirtyGroupDiscard()) { getWGroups().setText(""); getWGroups().setEditable(true); populateTable(createNewAnnotationGroup()); } } }; lsCopyGroup = new Listener() { @Override public void handleEvent(final Event event) { if (checkDirtyGroupDiscard()) { String originalName = getWGroups().getText(); ModelAnnotationGroup currentGroup = getTableComposite().getData(); if (StringUtils.isNotBlank(originalName) && currentGroup != null) { getWGroups().setText( BaseMessages.getString(PKG, "ModelAnnotation.NewAnnotation.CopyOf", originalName)); getWGroups().setEditable(true); ModelAnnotationGroup modelAnnotations = ObjectUtils.deepClone(currentGroup); modelAnnotations.setName(getWGroups().getText()); populateTable(modelAnnotations); } } } }; } protected ModelAnnotationGroup createNewAnnotationGroup() { return new ModelAnnotationGroup(); } protected void handleNewOrRenameGroups() { if (preventNewOrRename) { return; } final String currentGroupName = getTableComposite().getData().getName(); if (groupNameExists()) { Map<String, Listener> listenerMap = new LinkedHashMap<String, Listener>(); listenerMap.put(BaseMessages.getString(PKG, "System.Button.No"), new Listener() { @Override public void handleEvent(Event event) { getWGroups().setText(currentGroupName == null ? "" : currentGroupName); // revert to the current getWGroups().getCComboWidget().setFocus(); getWGroups().getCComboWidget().setEditable(true); } }); listenerMap.put(BaseMessages.getString(PKG, "System.Button.Yes"), new Listener() { @Override public void handleEvent(Event event) { onModelAnnotationDirty(); lsGroups.handleEvent(null); //load the group } }); WarningDialog warningDialog = new WarningDialog(shell, BaseMessages.getString(PKG, "ModelAnnotation.UnableToRename.Title"), BaseMessages.getString(PKG, "ModelAnnotation.UnableToRename.Message", getWGroups().getCComboWidget().getText()), listenerMap); warningDialog.open(); } else { if (StringUtils.isBlank(currentGroupName)) { logDebug("New Group..."); } else { logDebug("Renamed " + currentGroupName + " to " + getWGroups().getText()); markedForDeletion.push(currentGroupName); } onModelAnnotationDirty(); } setAnnotationsEditEnabled(true); } protected boolean groupNameExists() { String name = StringUtils.trim(getWGroups().getText()); String[] groupNames = getWGroups().getCComboWidget().getItems(); if (groupNames != null) { for (String groupName : groupNames) { if (StringUtils.equalsIgnoreCase(StringUtils.trim(groupName), StringUtils.trim(name))) { return true; } } } return false; } /** * @return continue */ protected boolean checkDirtyGroupDiscard() { if (modelAnnotationDirty) { preventNewOrRename = true; // suppress additional warnings Listener lsWarningYes = new Listener() { @Override public void handleEvent(final Event event) { try { input.saveToMetaStore(getMetaStore(), getTableComposite().getData()); modelAnnotationDirty = false; onModelAnnotationDirty(); preventNewOrRename = false; // reset } catch (Exception e) { showError(BaseMessages.getString(PKG, "ModelAnnotation.MetaStoreSaveError.Title"), BaseMessages.getString(PKG, "ModelAnnotation.MetaStoreSaveError.Message", e.getLocalizedMessage())); } } }; Listener lsWarningNo = new Listener() { @Override public void handleEvent(final Event event) { String groupName = (getTableComposite().getData()).getName(); if (groupName != null) { removeItem(getWGroups(), groupName); } modelAnnotationDirty = false; onModelAnnotationDirty(); preventNewOrRename = false; // reset } }; Listener lsWarningCancel = new Listener() { @Override public void handleEvent(final Event event) { String name = (getTableComposite().getData()).getName(); if (name != null) { getWGroups().setText((getTableComposite().getData()).getName()); // reset } preventNewOrRename = false; // reset } }; Map<String, Listener> listenerMap = new LinkedHashMap<String, Listener>(); listenerMap.put(BaseMessages.getString(PKG, "System.Button.Cancel"), lsWarningCancel); listenerMap.put(BaseMessages.getString(PKG, "System.Button.No"), lsWarningNo); listenerMap.put(BaseMessages.getString(PKG, "ModelAnnotation.UnsavedChangesWarning.Yes"), lsWarningYes); WarningDialog warningDialog = new WarningDialog(shell, BaseMessages.getString(PKG, "ModelAnnotation.UnsavedChangesWarning.Title"), BaseMessages.getString(PKG, "ModelAnnotation.UnsavedChangesWarning.Message", (getTableComposite().getData()).getName()), listenerMap); warningDialog.open(); } else { setAnnotationsEditEnabled(true); modelAnnotationDirty = false; onModelAnnotationDirty(); } return !modelAnnotationDirty; } protected void okay() { if (applyChanges()) { dispose(); } } protected void cancel() { stepname = null; dispose(); } @Override public void dispose() { super.dispose(); } protected void createOkCancelButtons() { // Create a horizontal separator wBottomHorizontalSeparator = new Label(shell, SWT.HORIZONTAL | SWT.SEPARATOR); FormData fdSepator = new FormData(); fdSepator.left = new FormAttachment(0, LEFT_MARGIN_OFFSET); // match the left offset of the help button fdSepator.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); fdSepator.bottom = new FormAttachment(wHelp, -15); // above help button wBottomHorizontalSeparator.setLayoutData(fdSepator); // Cancel Button wCancel = new Button(shell, SWT.PUSH); wCancel.setAlignment(SWT.CENTER); wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel") + " "); // add spaces to push left FormData fdCancel = new FormData(); fdCancel.top = new FormAttachment(wHelp, 0, SWT.TOP); fdCancel.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); wCancel.setLayoutData(fdCancel); // OK Button wOK = new Button(shell, SWT.PUSH); wOK.setAlignment(SWT.CENTER); wOK.setText(BaseMessages.getString(PKG, "System.Button.OK")); FormData fdOK = new FormData(); fdOK.top = new FormAttachment(wCancel, 0, SWT.TOP); fdOK.right = new FormAttachment(wCancel, -margin, SWT.LEFT); wOK.setLayoutData(fdOK); FormData fdApplyCont = new FormData(); fdApplyCont.top = new FormAttachment(wOK, 0, SWT.TOP); fdApplyCont.right = new FormAttachment(wOK, -margin, SWT.LEFT); fdApplyCont.left = new FormAttachment(wHelp, margin, SWT.RIGHT); Composite comp = new Composite(shell, SWT.NONE); comp.setLayoutData(fdApplyCont); RowLayout rl = new RowLayout(); rl.pack = true; rl.justify = true; rl.marginTop = 0; comp.setLayout(rl); props.setLook(comp); // Apply Button wApply = new Button(comp, SWT.PUSH); wApply.setAlignment(SWT.CENTER); wApply.setEnabled(false); wApply.setText(BaseMessages.getString(PKG, "System.Button.Apply")); RowData fdApply = new RowData(); wApply.setLayoutData(fdApply); // Add listeners wOK.addListener(SWT.Selection, lsOK); wCancel.addListener(SWT.Selection, lsCancel); wApply.addListener(SWT.Selection, lsApply); } @Override protected Button createHelpButton(final Shell shell, final StepMeta stepMeta, final PluginInterface plugin) { wHelp = super.createHelpButton(shell, stepMeta, plugin); // capture help button from base class FormData fdHelp = new FormData(); fdHelp.bottom = new FormAttachment(100, -10); fdHelp.left = new FormAttachment(0, LEFT_MARGIN_OFFSET); wHelp.setLayoutData(fdHelp); return wHelp; } protected Control createStepNameWidget() { // Create Step Name label wlStepname = new Label(shell, SWT.LEFT); wlStepname.setText(getStepName()); props.setLook(wlStepname); fdlStepname = new FormData(); fdlStepname.left = new FormAttachment(0, LEFT_MARGIN_OFFSET); fdlStepname.top = new FormAttachment(0, 10); wlStepname.setLayoutData(fdlStepname); // Create Step Name Text wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER); wStepname.setText(stepname); wStepname.addModifyListener(lsMod); props.setLook(wStepname); fdStepname = new FormData(); fdStepname.top = new FormAttachment(wlStepname, 5); fdStepname.left = new FormAttachment(0, LEFT_MARGIN_OFFSET + 2); fdStepname.right = new FormAttachment(0, LEFT_MARGIN_OFFSET + 252); wStepname.setLayoutData(fdStepname); // Create a horizontal separator Label wSeparator = new Label(shell, SWT.HORIZONTAL | SWT.SEPARATOR); FormData fdSepator = new FormData(); fdSepator.top = new FormAttachment(wStepname, 15, SWT.BOTTOM); fdSepator.left = new FormAttachment(0, LEFT_MARGIN_OFFSET + 2); fdSepator.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); wSeparator.setLayoutData(fdSepator); wIcon = new Label(shell, SWT.CENTER); wIcon.setImage(getImageIcon()); FormData fdIcon = new FormData(); fdIcon.top = new FormAttachment(0, 15); fdIcon.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); wIcon.setLayoutData(fdIcon); props.setLook(wIcon); return wSeparator; } protected Control createDescription(Control topWidget) { Label wlDescription = new Label(shell, SWT.LEFT); wlDescription.setText(BaseMessages.getString(PKG, "SharedDimension.Dialog.Description.Label")); props.setLook(wlDescription); FormData fdlDescription = new FormData(); fdlDescription.top = new FormAttachment(topWidget, 10); fdlDescription.left = new FormAttachment(0, LEFT_MARGIN_OFFSET); fdlDescription.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); wlDescription.setLayoutData(fdlDescription); wDescription = new StyledText(shell, SWT.MULTI | SWT.BORDER | SWT.WRAP); props.setLook(wDescription); FormData fdDescription = new FormData(); fdDescription.height = 50; fdDescription.top = new FormAttachment(wlDescription, 5); fdDescription.left = new FormAttachment(0, LEFT_MARGIN_OFFSET); fdDescription.right = new FormAttachment(100, RIGHT_MARGIN_OFFSET); wDescription.setLayoutData(fdDescription); // Add Listener wDescription.addListener(SWT.FocusOut, new Listener() { @Override public void handleEvent(Event event) { if (input.getModelAnnotations() != null && textChanged(wDescription, StringUtils.defaultIfBlank(input.getModelAnnotations().getDescription(), ""))) { modelAnnotationDirty = true; onModelAnnotationDirty(); } } }); return wDescription; } protected void afterOpen() { // Do nothing. Optional } protected String envSub(String var) { return this.transMeta.environmentSubstitute(var); } protected void setDirtyFlag(final ModelAnnotationGroup g1, final ModelAnnotationGroup g2) { // compare if model annotations changed if (groupChanged(g1, g2)) { modelAnnotationDirty = true; onModelAnnotationDirty(); } else { modelAnnotationDirty = false; } } private boolean groupChanged(final ModelAnnotationGroup g1, final ModelAnnotationGroup g2) { try { if (!EqualsBuilder.reflectionEquals(g1, g2)) { return true; } // check model annotations for (int i = 0; i < g1.size(); i++) { // check fields except for annotation field if (!EqualsBuilder.reflectionEquals(g1.get(i), g2.get(i), new String[] { "annotation" })) { return true; } // manually check annotation properties Map<String, Serializable> g1Properties = g1.get(i).describeAnnotation(); Map<String, Serializable> g2Properties = g2.get(i).describeAnnotation(); if (!EqualsBuilder.reflectionEquals(g1Properties, g2Properties)) { return true; // check mainly if one is null and the other isn't } if (g1Properties != null && g2Properties != null) { if (!g1Properties.equals(g2Properties)) { return true; // deep check } } } return false; // no change } catch (Exception e) { return true; } } protected void getFields() { final ModelAnnotationGroup groupCopy = ObjectUtils.deepClone(getTableComposite().getData()); getTableComposite().getFields(getParent(), input, transMeta, stepname, new Listener() { @Override public void handleEvent(Event event) { if (event instanceof ModelAnnotationEvent) { ModelAnnotationEvent e = (ModelAnnotationEvent) event; setDirtyFlag(groupCopy, e.getModelAnnotations()); } } }); } protected void editAnnotation() { final ModelAnnotationGroup groupCopy = ObjectUtils.deepClone(getTableComposite().getData()); getTableComposite().editAnnotation(shell, input, transMeta, stepname, getMetaStore(), new Listener() { @Override public void handleEvent(Event event) { if (event instanceof ModelAnnotationEvent) { ModelAnnotationEvent e = (ModelAnnotationEvent) event; if (!modelAnnotationDirty) { setDirtyFlag(groupCopy, e.getModelAnnotations()); } populateTable(e.getModelAnnotations()); // Update Table } } }); } protected void deleteAnnotation() { getTableComposite().deleteAnnotation(); modelAnnotationDirty = true; onModelAnnotationDirty(); } protected void populateTableFromMetastore() { populateTableFromMetastore(!StringUtil.isVariable(getSelectedModelAnnotationGroupName())); } protected void populateTableFromMetastore(boolean warnNotFound) { try { String groupName = envSub(getSelectedModelAnnotationGroupName()); ModelAnnotationGroup modelAnnotations = null; if (!StringUtil.isEmpty(groupName)) { modelAnnotations = getModelAnnotationManger().readGroup(groupName, getMetaStore()); } if (modelAnnotations == null) { if (warnNotFound) { Map<String, Listener> listenerMap = new LinkedHashMap<String, Listener>(); listenerMap.put(BaseMessages.getString(PKG, "System.Button.OK"), new Listener() { @Override public void handleEvent(final Event event) { } }); WarningDialog warningDialog = new WarningDialog(shell, BaseMessages.getString(PKG, missingTitleKey()), BaseMessages.getString(PKG, missingMessageKey(), getSelectedModelAnnotationGroupName()), listenerMap); warningDialog.open(); } modelAnnotations = createNewAnnotationGroup(); } populateTable(modelAnnotations); } catch (MetaStoreException e) { log.logError(e.getLocalizedMessage(), e); populateTable(new ModelAnnotationGroup()); } } protected abstract String missingMessageKey(); protected abstract String missingTitleKey(); protected void populateCategories(final String selectedCategory, final boolean sharedDimensions) { boolean isShared = selectedCategory != null; if (getWGroups().getItemCount() > 0) { getWGroups().removeAll(); } try { final List<String> groupNames = getGroupNames(sharedDimensions); boolean foundCategory = false; for (int i = 0; i < groupNames.size(); i++) { final String groupName = groupNames.get(i); getWGroups().add(groupName); if (isShared && input.getModelAnnotationCategory().equals(groupName)) { getWGroups().select(i); foundCategory = true; } } if ((isShared && !foundCategory) || (StringUtils.isNotBlank(input.getModelAnnotationCategory()) && StringUtils.equals(selectedCategory, envSub(input.getModelAnnotationCategory())))) { // display var name getWGroups().setText(input.getModelAnnotationCategory()); } } catch (Exception e) { log.logError(e.getLocalizedMessage(), e); } } protected void setAnnotationsEditEnabled(boolean enabled) { getTableComposite().setEnabled(enabled); wDescription.setEnabled(enabled); if (enabled) { props.setLook(wDescription); } else { wDescription.setBackground(GUIResource.getInstance().getColorDemoGray()); } } protected void populateTable(final ModelAnnotationGroup modelAnnotations) { getTableComposite().populateTable(modelAnnotations, transMeta, stepname, shell); if (wDescription != null && modelAnnotations != null) { wDescription.setText(StringUtils.defaultIfBlank(modelAnnotations.getDescription(), "")); } } protected boolean textChanged(StyledText textWidget, String text) { if (textWidget != null && !StringUtils.equals(textWidget.getText(), text)) { return true; } return false; } protected List<String> getGroupNames(boolean sharedDimension) { List<String> filteredGroupNames = new ArrayList<String>(); try { final List<ModelAnnotationGroup> groupNames = getModelAnnotationManger().listGroups(getMetaStore()); if (groupNames != null) { for (ModelAnnotationGroup modelAnnotationGroup : groupNames) { if (sharedDimension) { if (modelAnnotationGroup.isSharedDimension()) { filteredGroupNames.add(modelAnnotationGroup.getName()); } } else { if (!modelAnnotationGroup.isSharedDimension()) { filteredGroupNames.add(modelAnnotationGroup.getName()); } } } } } catch (Exception e) { log.logError(e.getLocalizedMessage(), e); } return filteredGroupNames; } protected boolean removeItem(ComboVar combo, String elementName) { int idx = combo.getCComboWidget().indexOf(elementName); if (idx >= 0) { combo.getCComboWidget().remove(idx); return true; } return false; } public void linkAnnotations(final ComboVar combo, final String name, final String description, final Event parent) { final String groupName = envSub(name); if (!checkValidName(name)) { parent.doit = false; return; } try { // check if already exists ModelAnnotationGroup modelAnnotations = getModelAnnotationManger().readGroup(groupName, getMetaStore()); if (modelAnnotations != null) { Listener lsWarningYes = new Listener() { @Override public void handleEvent(final Event event) { linkAnnotations(combo, groupName, description); } }; Listener lsWarningNo = new Listener() { @Override public void handleEvent(final Event event) { // stop parent action parent.doit = false; } }; Map<String, Listener> listenerMap = new LinkedHashMap<String, Listener>(); listenerMap.put(BaseMessages.getString(PKG, "System.Button.No"), lsWarningNo); listenerMap.put(BaseMessages.getString(PKG, "ModelAnnotation.AnnotationGroupExists.Yes"), lsWarningYes); WarningDialog warningDialog = new WarningDialog(shell, BaseMessages.getString(PKG, "ModelAnnotation.AnnotationGroupExists.Title"), BaseMessages.getString(PKG, "ModelAnnotation.AnnotationGroupExists.Message", groupName), listenerMap); warningDialog.open(); } else { linkAnnotations(combo, groupName, description); } } catch (MetaStoreException e) { log.logError(e.getLocalizedMessage(), e); } } protected void linkAnnotations(final ComboVar combo, final String groupName, final String description) { removeItem(combo, groupName); combo.add(groupName); combo.select(combo.getItemCount() - 1); if (wDescription != null) { wDescription.setText(StringUtils.defaultIfBlank(description, "")); } (getTableComposite().getData()).setDescription(description); (getTableComposite().getData()).setName(groupName); modelAnnotationDirty = true; onLinkAnnotations(); } protected boolean checkValidName(final String name) { try { input.checkValidName(name); return true; } catch (KettleException e) { showError(BaseMessages.getString(PKG, "ModelAnnotation.MetaStoreInvalidName.Title"), e.getLocalizedMessage()); return false; } } protected void discardAll(final ComboVar combo, final String selectItem) { (getTableComposite().getData()).clear(); getTableComposite().refresh(); String[] items = combo.getItems(); for (int i = 0; i < items.length; i++) { if (items[i].equals(selectItem)) { combo.select(i); } } populateTableFromMetastore(); onDiscardAll(); } protected void deleteStaleGroups(final boolean sharedDimensions) { // Delete groups that need to be deleted - i.e. renamed groups while (!markedForDeletion.empty()) { try { String groupName = markedForDeletion.pop(); if (getModelAnnotationManger().containsGroup(groupName, getMetaStore())) { getModelAnnotationManger().deleteGroup(groupName, getMetaStore()); } } catch (MetaStoreException e) { logError(e.getLocalizedMessage(), e); } } populateCategories(getWGroups().getText(), sharedDimensions); } public void showInfo(String title, String message) { SpoonInterface spoon = getSpoon(); spoon.messageBox(message, title, false, Const.INFO); } public void showError(String title, String message) { Map<String, Listener> listenerMap = new HashMap<String, Listener>(); listenerMap.put(BaseMessages.getString(PKG, "System.Button.OK"), new Listener() { @Override public void handleEvent(final Event event) { } }); new WarningDialog(shell, title, message, listenerMap).open(); } protected void resizeSummaryColumn(final ModelAnnotationsTableComposite tableComposite) { // Resize certain widgets when dialog is resized shell.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent e) { if (tableComposite != null) { // calculate widths of first 3 columns of table int width = 0; for (int i = 0; i < 3; i++) { width += tableComposite.getTable().getColumn(i).getWidth(); } // expand summary column to take up the rest of the space in the table tableComposite.getTable().getColumn(2).setWidth(tableComposite.getTable().getSize().x - width); } } }); } protected SpoonInterface getSpoon() { return SpoonFactory.getInstance(); } protected void onLinkAnnotations() { onModelAnnotationDirty(); } protected void onDiscardAll() { onModelAnnotationDirty(); } protected void onModelAnnotationDirty() { wApply.setEnabled(true); } protected abstract String getDialogTitle(); protected abstract String getStepName(); protected abstract Image getImageIcon(); protected abstract void createContent(Control topWidget); protected abstract ModelAnnotationManager getModelAnnotationManger(); protected abstract ModelAnnotationsTableComposite getTableComposite(); protected abstract String getSelectedModelAnnotationGroupName(); protected abstract boolean applyChanges(); protected abstract ComboVar getWGroups(); }