public class LanguageObjectBuilderTreeViewer extends TreeViewer implements ILanguageObjectInputProvider, UiConstants { private static final String PREFIX = I18nUtil.getPropertyPrefix(LanguageObjectBuilderTreeViewer.class); LanguageObjectContentProvider contentProvider; private LanguageObject langObj; public LanguageObjectBuilderTreeViewer(Composite theParent) { super(theParent, SWT.NONE); contentProvider = new LanguageObjectContentProvider(); setContentProvider(contentProvider); setLabelProvider(new LanguageObjectLabelProvider()); getTree().setLayoutData(new GridData(GridData.FILL_BOTH)); } public void addUndefinedAndCriteria() { addUndefinedCriteria((Criteria) getSelectedObject(), true); } private void addUndefinedCriteria(Criteria theCriteria, boolean theAndFlag) { CoreArgCheck.isNotNull(theCriteria); // should not be calling if null Object newSelection = StructuredSelection.EMPTY; if (theCriteria instanceof CompoundCriteria) { CompoundCriteria criteria = (CompoundCriteria) theCriteria; criteria.addCriteria((Criteria) null); refresh(true); newSelection = contentProvider.getChildAt((criteria.getCriteriaCount() - 1), criteria); } else if (theCriteria instanceof NotCriteria) { // the contained Criteria must be a CompoundCriteria addUndefinedCriteria(((NotCriteria) theCriteria).getCriteria(), theAndFlag); } else if (theCriteria instanceof PredicateCriteria) { CompoundCriteria compoundCriteria = new CompoundCriteria(); compoundCriteria.setOperator((theAndFlag) ? CompoundCriteria.AND : CompoundCriteria.OR); compoundCriteria.addCriteria(theCriteria); compoundCriteria.addCriteria((Criteria) null); // modify parent here LanguageObject parent = (LanguageObject) contentProvider.getParent(theCriteria); int index = contentProvider.getChildIndex(theCriteria); if (parent == null) { setLanguageObject(compoundCriteria); refresh(true); // select undefined criteria newSelection = contentProvider.getChildAt(1, contentProvider.getRoot()); expandToLevel(newSelection, ALL_LEVELS); } else if ((parent instanceof NotCriteria) || (parent instanceof CompoundCriteria)) { CompoundCriteria criteria = null; if (parent instanceof NotCriteria) { // then NotCriteria's contained criteria must be a CompoundCriteria criteria = (CompoundCriteria) ((NotCriteria) theCriteria).getCriteria(); } else { criteria = (CompoundCriteria) parent; } List crits = criteria.getCriteria(); crits.set(index, compoundCriteria); refresh(true); // select undefined criteria newSelection = contentProvider.getChildAt(1, compoundCriteria); } else { CoreArgCheck.isTrue( false, Util.getString( PREFIX + "unexpectedType", // $NON-NLS-1$ new Object[] {"addUndefinedCriteria", parent.getClass()})); // $NON-NLS-1$ } } // select appropriate tree item final Object selection = newSelection; Display.getDefault() .asyncExec( new Runnable() { public void run() { setSelection(new StructuredSelection(selection)); } }); } public void addUndefinedOrCriteria() { addUndefinedCriteria((Criteria) getSelectedObject(), false); } private boolean canDelete(Object theLangObj) { boolean result = true; LanguageObject parent = (LanguageObject) contentProvider.getParent(theLangObj); if (parent == null) { // object is root. can only delete if not undefined result = !isUndefined(theLangObj); } else if (parent instanceof Function) { // all function arguments except converstion type constants can be deleted if (theLangObj instanceof Constant) { result = !BuilderUtils.isConversionType((Constant) theLangObj); } } else if (parent instanceof NotCriteria) { // get compound criteria and ask again NotCriteria notCrit = (NotCriteria) parent; Criteria criteria = notCrit.getCriteria(); // NotCriteria must contain either another NotCriteria or a CompoundCriteria while (!(criteria instanceof CompoundCriteria)) { // must be a NotCriteria criteria = ((NotCriteria) criteria).getCriteria(); result = canDelete(criteria); } } return result; } public boolean canDeleteSelection() { return canDelete(getSelectedObject()); } private void delete(Object theLangObj) { if (canDelete(theLangObj)) { boolean doSelect = true; // // set the parent object to reflect the change in it's child. parent can't be undefined. // Object newSelection = StructuredSelection.EMPTY; LanguageObject parent = (LanguageObject) contentProvider.getParent(theLangObj); if (parent == null) { // object being delete is root language object setLanguageObject(null); // resets undefined count refresh(true); newSelection = contentProvider.getRoot(); expandToLevel(newSelection, ALL_LEVELS); } else if (parent instanceof Function) { // set the arg to null in parent int index = contentProvider.getChildIndex(theLangObj); Expression[] args = ((Function) parent).getArgs(); args[index] = null; refresh(true); newSelection = contentProvider.getChildAt(index, parent); } else if (parent instanceof Criteria) { if (contentProvider.getChildCount(parent) > 1) { CompoundCriteria compoundCriteria = null; // parent is either a compound criteria or not criteria if (parent instanceof CompoundCriteria) { compoundCriteria = (CompoundCriteria) parent; } else { // NotCriteria NotCriteria notCrit = (NotCriteria) parent; Criteria criteria = notCrit.getCriteria(); // NotCriteria must contain either another NotCriteria or a CompoundCriteria while (!(criteria instanceof CompoundCriteria)) { // must be a NotCriteria criteria = ((NotCriteria) criteria).getCriteria(); } compoundCriteria = (CompoundCriteria) criteria; } List crits = compoundCriteria.getCriteria(); int index = contentProvider.getChildIndex(theLangObj); // CompoundCriteria has to have at least 2 criteria to be compound. if it has more than 2 // just delete the selected obj. if there are exactly 2 criteria than this special // processing block occurs. if (contentProvider.getChildCount(parent) == 2) { int siblingIndex = (index == 0) ? 1 : 0; // if deleting this node would leave just an undefined node under the parent, delete // parent if (isUndefined(contentProvider.getChildAt(siblingIndex, parent))) { delete(parent); } else { // sibling is not undefined // if deleting an undefined node, delete from parent. this will leave one node // under the parent. if (isUndefined(theLangObj)) { crits.remove(index); // selection taken care of below in block checking for size of 1 } else { // replace deleted node with undefined node crits.set(index, (Criteria) null); refresh(true); newSelection = contentProvider.getChildAt(index, parent); } } } else { // just remove from parent crits.remove(index); refresh(true); newSelection = parent; } if (crits.size() == 1) { // need to modify parent node with the child (refresh done there) modifyLanguageObject( parent, (LanguageObject) contentProvider.getChildAt(0, parent), false); doSelect = false; // modify does select } } } if (doSelect) { final Object selection = newSelection; Display.getDefault() .asyncExec( new Runnable() { public void run() { setSelection(new StructuredSelection(selection)); } }); } } } public void deleteSelection() { delete(getSelectedObject()); } /** * @see * com.metamatrix.modeler.transformation.ui.builder.ILanguageObjectInputProvider#getLanguageObject() */ public LanguageObject getLanguageObject() { return langObj; } // returns null if no selection // if there is a selection it will either by a LanguageObject or BuilderUtils.UNDEFINED public Object getSelectedObject() { Object result = null; IStructuredSelection selection = (IStructuredSelection) getSelection(); if (selection.size() == 1) { result = selection.getFirstElement(); } return result; } /** * Indicates if the given object has undefined children. * * @param theLangObj the object being queried * @return <code>true</code> if undefined child exist; <code>false</code> otherwise. */ public boolean hasUndefinedChild(Object theLangObj) { boolean result = false; Object[] kids = contentProvider.getChildren(theLangObj); if (kids.length > 0) { // go in reverse order since it is more likely undefined will be at the end for (int i = (kids.length - 1); i >= 0; i--) { if (isUndefined(kids[i])) { result = true; } else { result = hasUndefinedChild(kids[i]); } if (result) { break; } } } return result; } public boolean isComplete() { Object root = contentProvider.getRoot(); boolean result = ((root == null) || (isUndefined(root))) ? false : !hasUndefinedChild(root); return result; } public boolean isUndefined(Object theLangObj) { return ((theLangObj == null) || theLangObj.equals(BuilderUtils.UNDEFINED)); } private void modifyLanguageObject( Object theObject, LanguageObject theNewValue, boolean retainSelection) { CoreArgCheck.isNotNull(theNewValue); // should not be null when modifying // // set the parent object to reflect the change in it's child. parent's can't be undefined // Object newSelection = StructuredSelection.EMPTY; LanguageObject parent = (LanguageObject) contentProvider.getParent(theObject); Object newValue = theNewValue; if (parent == null) { // root language object setLanguageObject((LanguageObject) newValue); refresh(true); newSelection = contentProvider.getRoot(); expandToLevel(newSelection, ALL_LEVELS); if (newSelection instanceof Function) { Function function = (Function) newSelection; if (function.getArgs().length > 0) { newSelection = contentProvider.getChildAt(0, function); } } } else if (parent instanceof Function) { // set the arg to new value in parent int index = contentProvider.getChildIndex(theObject); Expression[] args = ((Function) parent).getArgs(); args[index] = (Expression) newValue; refresh(true); expandToLevel(parent, ALL_LEVELS); newSelection = contentProvider.getChildAt(index, parent); if (!retainSelection) { if (newSelection instanceof Function) { // if function arg change to be a function, select first function arg if (contentProvider.getChildCount(newSelection) > 0) { newSelection = contentProvider.getChildAt(0, newSelection); } } else { // select next sibling function arg if exists if ((args.length - 1) > index) { newSelection = contentProvider.getChildAt(index + 1, parent); } else if (index > 0) { newSelection = contentProvider.getChildAt(0, parent); } else { newSelection = contentProvider.getChildAt(index, parent); } } } } else if (parent instanceof Criteria) { // theLangObj must also be a Criteria // since NotCriteria aren't really edited in the editor (their contained criteria is). Need to // save the state in order to restore it when modifying Criteria newCriteria = (Criteria) newValue; int index = contentProvider.getChildIndex(theObject); if ((parent instanceof CompoundCriteria) || (parent instanceof NotCriteria)) { CompoundCriteria compoundCriteria = null; if (parent instanceof CompoundCriteria) { compoundCriteria = (CompoundCriteria) parent; } else { compoundCriteria = (CompoundCriteria) ((NotCriteria) parent).getCriteria(); } List criteriaCollection = compoundCriteria.getCriteria(); criteriaCollection.set(index, newCriteria); refresh(true); if (retainSelection) { newSelection = criteriaCollection.get(index); } else { // set selection to next sibling criteria or to the first sibling if ((criteriaCollection.size() - 1) > index) { newSelection = criteriaCollection.get(index + 1); } else if (index > 0) { newSelection = criteriaCollection.get(0); } else { newSelection = contentProvider.getChildAt(index + 1, parent); } } } else { CoreArgCheck.isTrue( false, Util.getString( PREFIX + "unexpectedType", // $NON-NLS-1$ new Object[] { "modifyLanguageObject", //$NON-NLS-1$ parent.getClass().getName() })); } expandToLevel(parent, ALL_LEVELS); } // select next node setSelection( (newSelection == null) ? StructuredSelection.EMPTY : new StructuredSelection(newSelection)); } public void modifyNotCriteriaStatus() { Object selectedObj = getSelectedObject(); CoreArgCheck.isNotNull(selectedObj); // should not be calling if no row selected if (selectedObj instanceof NotCriteria) { modifySelectedItem(((NotCriteria) selectedObj).getCriteria(), true); } else if (selectedObj instanceof Criteria) { modifySelectedItem(new NotCriteria((Criteria) selectedObj), true); } else if (isUndefined(selectedObj)) { CoreArgCheck.isTrue( false, Util.getString( PREFIX + "unexpectedType", // $NON-NLS-1$ new Object[] {"modifyNotCriteriaStatus", BuilderUtils.UNDEFINED})); // $NON-NLS-1$ } else { CoreArgCheck.isTrue( false, Util.getString( PREFIX + "unexpectedType", // $NON-NLS-1$ new Object[] {"modifyNotCriteriaStatus", selectedObj.getClass()})); // $NON-NLS-1$ } } public void modifySelectedItem(LanguageObject theLangObj, boolean retainSelection) { modifyLanguageObject(getSelectedObject(), theLangObj, retainSelection); } public void selectRoot() { // put this in the back of the UI thread event queue. // at startup the listeners we're working. this makes sure the listeners have all been wired. Display.getDefault() .asyncExec( new Runnable() { public void run() { setSelection(new StructuredSelection(contentProvider.getRoot())); } }); } public void setLanguageObject(LanguageObject theLangObj) { langObj = theLangObj; setInput(this); } }
/** AbstractLanguageObjectBuilder */ public abstract class AbstractLanguageObjectBuilder extends Dialog implements UiConstants { // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTANTS // ///////////////////////////////////////////////////////////////////////////////////////////// private static final String PREFIX = I18nUtil.getPropertyPrefix(AbstractLanguageObjectBuilder.class); // ///////////////////////////////////////////////////////////////////////////////////////////// // FIELDS // ///////////////////////////////////////////////////////////////////////////////////////////// private IAction deleteAction; private ILanguageObjectEditor editor; private LanguageObject savedSelection; protected LanguageObject savedLangObj; // ///////////////////////////////////////////////////////////////////////////////////////////// // CONTROLS // ///////////////////////////////////////////////////////////////////////////////////////////// protected Button btnSet; protected Button btnReset; private Label lblTitle; private Composite pnlEditor; private Composite pnlEditorDetail; LanguageObjectBuilderTreeViewer treeViewer; private SqlDisplayPanel currentSql; private SqlDisplayPanel originalSql; private CLabel originalLanguageObjLabel; // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS // ///////////////////////////////////////////////////////////////////////////////////////////// protected AbstractLanguageObjectBuilder(Shell theParent, String theTitle) { super(theParent, theTitle); } // ///////////////////////////////////////////////////////////////////////////////////////////// // METHODS // ///////////////////////////////////////////////////////////////////////////////////////////// @Override public void create() { super.create(); editor = createEditor(pnlEditorDetail); editor .getModel() .addModelListener( new ILanguageObjectEditorModelListener() { public void modelChanged(LanguageObjectEditorModelEvent theEvent) { handleModelChanged(); } }); lblTitle.setText(editor.getTitle()); Composite pnlEditorButtons = new Composite(pnlEditor, SWT.NONE); pnlEditorButtons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER)); pnlEditorButtons.setLayout(new GridLayout()); // // pnlEditorButtons contents // btnSet = new Button(pnlEditorButtons, SWT.NONE); btnSet.setEnabled(false); btnSet.setText(Util.getString(PREFIX + "btnSet")); // $NON-NLS-1$ btnSet.setToolTipText(Util.getString(PREFIX + "btnSet.tip")); // $NON-NLS-1$ btnSet.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent theEvent) { handleSetSelected(); } }); btnReset = new Button(pnlEditorButtons, SWT.NONE); btnReset.setEnabled(false); btnReset.setText(Util.getString(PREFIX + "btnReset")); // $NON-NLS-1$ btnReset.setToolTipText(Util.getString(PREFIX + "btnReset.tip")); // $NON-NLS-1$ btnReset.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent theEvent) { handleResetSelected(); } }); setLanguageObject(null); // needed to establish the viewer input // select root tree node after all construction is finished Display.getDefault() .asyncExec( new Runnable() { public void run() { treeViewer.selectRoot(); } }); } /* (non-Javadoc) * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ @Override protected Control createDialogArea(Composite theParent) { originalLanguageObjLabel = WidgetFactory.createLabel(theParent, CoreStringUtil.Constants.EMPTY_STRING); Composite pnlContents = (Composite) super.createDialogArea(theParent); // // main panel contents // CTabFolder tabFolder = WidgetFactory.createTabFolder(pnlContents); // // tabFolder contents - 2 tabs (Tree, SQL Text), each with a splitter // CTabItem treeTab = WidgetFactory.createTab(tabFolder, Util.getString(PREFIX + "treeTab")); // $NON-NLS-1$ treeTab.setToolTipText(Util.getString(PREFIX + "treeTab.tip")); // $NON-NLS-1$ SashForm treeTabSash = new SashForm(tabFolder, SWT.VERTICAL); treeTabSash.setLayoutData(new GridData(GridData.FILL_BOTH)); treeTab.setControl(treeTabSash); CTabItem sqlTab = WidgetFactory.createTab(tabFolder, Util.getString(PREFIX + "sqlTab")); // $NON-NLS-1$ sqlTab.setToolTipText(Util.getString(PREFIX + "sqlTab.tip")); // $NON-NLS-1$ SashForm sqlTabSash = new SashForm(tabFolder, SWT.VERTICAL); sqlTabSash.setLayoutData(new GridData(GridData.FILL_BOTH)); sqlTab.setControl(sqlTabSash); // // treeTab contents // ViewForm formTree = new ViewForm(treeTabSash, SWT.BORDER); Composite pnlTree = new Composite(formTree, SWT.NO_TRIM); formTree.setContent(pnlTree); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; pnlTree.setLayout(layout); pnlTree.setLayoutData(new GridData(GridData.FILL_BOTH)); ViewForm formEditor = new ViewForm(treeTabSash, SWT.BORDER); pnlEditor = new Composite(formEditor, SWT.NO_TRIM); formEditor.setContent(pnlEditor); pnlEditor.setLayoutData(new GridData(GridData.FILL_BOTH)); lblTitle = new Label(formEditor, SWT.CENTER); lblTitle.setBackground(BuilderUtils.COLOR_HIGHLIGHT); formEditor.setTopLeft(lblTitle); treeTabSash.setWeights(new int[] {30, 70}); // // sqlTab contents // ViewForm formCurrentSql = new ViewForm(sqlTabSash, SWT.BORDER); ViewForm formOriginalSql = new ViewForm(sqlTabSash, SWT.BORDER); // // formCurrentSql contents // Composite pnlCurrentSql = new Composite(formCurrentSql, SWT.NONE); formCurrentSql.setContent(pnlCurrentSql); pnlCurrentSql.setLayout(new GridLayout()); pnlCurrentSql.setLayoutData(new GridData(GridData.FILL_BOTH)); currentSql = new SqlDisplayPanel(pnlCurrentSql); currentSql.setLayoutData(new GridData(GridData.FILL_BOTH)); CLabel lblCurrent = new CLabel(formCurrentSql, SWT.NONE); lblCurrent.setBackground(BuilderUtils.COLOR_HIGHLIGHT); lblCurrent.setText(Util.getString(PREFIX + "lblCurrent")); // $NON-NLS-1$ lblCurrent.setToolTipText(Util.getString(PREFIX + "lblCurrent.tip")); // $NON-NLS-1$ formCurrentSql.setTopLeft(lblCurrent); // // formOriginalSql contents // Composite pnlOriginalSql = new Composite(formOriginalSql, SWT.NONE); formOriginalSql.setContent(pnlOriginalSql); pnlOriginalSql.setLayout(new GridLayout()); pnlOriginalSql.setLayoutData(new GridData(GridData.FILL_BOTH)); originalSql = new SqlDisplayPanel(pnlOriginalSql); originalSql.setLayoutData(new GridData(GridData.FILL_BOTH)); CLabel lblOriginal = new CLabel(formOriginalSql, SWT.NONE); lblOriginal.setBackground(BuilderUtils.COLOR_HIGHLIGHT); lblOriginal.setText(Util.getString(PREFIX + "lblOriginal")); // $NON-NLS-1$ lblOriginal.setToolTipText(Util.getString(PREFIX + "lblOriginal.tip")); // $NON-NLS-1$ formOriginalSql.setTopLeft(lblOriginal); // // pnlTree contents - 2 columns (tree viewer, button panel) // layout = new GridLayout(); layout.numColumns = 2; layout.marginHeight = 0; layout.marginWidth = 0; pnlTree.setLayout(layout); treeViewer = new LanguageObjectBuilderTreeViewer(pnlTree); treeViewer.addSelectionChangedListener( new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent theEvent) { handleTreeSelection(); } }); MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener( new IMenuListener() { public void menuAboutToShow(IMenuManager theMenuMgr) { fillContextMenu(theMenuMgr); } }); treeViewer.getTree().setMenu(menuMgr.createContextMenu(treeViewer.getTree())); Composite pnlButtons = new Composite(pnlTree, SWT.NONE); pnlButtons.setLayout(new GridLayout()); createTreeButtons(pnlButtons); // // pnlEditor contents // layout = new GridLayout(); layout.numColumns = 2; pnlEditor.setLayout(layout); pnlEditorDetail = new Composite(pnlEditor, SWT.NONE); pnlEditorDetail.setLayoutData(new GridData(GridData.FILL_BOTH)); pnlEditorDetail.setLayout(new GridLayout()); return pnlContents; } protected abstract ILanguageObjectEditor createEditor(Composite theParent); /** * Creates buttons that interact with the tree. * * @param theParent the panel where the buttons are contained */ protected void createTreeButtons(Composite theParent) { Runnable deleteRunner = new Runnable() { public void run() { handleDeleteSelected(); } }; deleteAction = new DeleteViewerObjectAction(theParent, deleteRunner); } protected void fillContextMenu(IMenuManager theMenuMgr) { theMenuMgr.add(deleteAction); } public ILanguageObjectEditor getEditor() { return editor; } /* (non-Javadoc) * @see com.metamatrix.query.internal.ui.builder.ILanguageObjectInputProvider#getLanguageObject() */ public LanguageObject getLanguageObject() { return treeViewer.getLanguageObject(); } /** * Gets the saved <code>LanguageObject</code>. * * @return the saved <code>LanguageObject</code> or <code>null</code> */ protected LanguageObject getSavedLanguageObject() { return savedLangObj; } /** * Gets a title for the builder. Title is appropriate for use as a dialog title. * * @return the builder title */ @Override public abstract String getTitle(); protected LanguageObjectBuilderTreeViewer getTreeViewer() { return treeViewer; } protected void handleDeleteSelected() { editor.clear(); treeViewer.deleteSelection(); // update SQL text setCurrentSql(treeViewer.getLanguageObject()); editor.acceptFocus(); } void handleModelChanged() { boolean isEnabled = false; boolean isComplete = false; boolean hasChanged = false; isEnabled = editor.isEnabled(); if (isEnabled) { isComplete = editor.isComplete(); } if (isComplete) { hasChanged = editor.hasChanged(); } boolean state = (isEnabled && isComplete && hasChanged); btnSet.setEnabled(state); btnReset.setEnabled(state); setCurrentSql(treeViewer.getLanguageObject()); // set enable/disable status of buttons setEnabledStatus(); } protected void handleResetSelected() { editor.reset(); // put focus back on editor from the reset button editor.acceptFocus(); } protected void handleSetSelected() { editor.save(); // need the editor's language object in order to update tree. // the language object should never be null. if it was this handler should not have been called LanguageObject langObj = editor.getLanguageObject(); CoreArgCheck.isNotNull( langObj, Util.getString( PREFIX + "nullLangObj", // $NON-NLS-1$ new Object[] {"handleSetSelected"})); // $NON-NLS-1$ // update tree treeViewer.modifySelectedItem(langObj, false); // update SQL text setCurrentSql(treeViewer.getLanguageObject()); // put focus back on editor from the set button editor.acceptFocus(); } protected void handleTreeSelection() { IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection(); Object selectedObj = selection.getFirstElement(); if (selectedObj == null) { savedSelection = null; if (editor.isEnabled()) { editor.setEnabled(false); } } else { // selection with either be a LanguageObject or an Undefined object (String) savedSelection = (selectedObj instanceof LanguageObject) ? (LanguageObject) selectedObj : null; } setEditorLanguageObject(savedSelection); // set enable/disable status of buttons setEnabledStatus(); } protected boolean isTreeSelectionRoot() { boolean isRoot = false; IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection(); if (selection.size() > 0) { Tree tree = treeViewer.getTree(); // We are assuming that the tree is single-selection. TreeItem treeItem = tree.getSelection()[0]; TreeItem parentItem = treeItem.getParentItem(); isRoot = (parentItem == null); } return isRoot; } protected void setCurrentSql(LanguageObject theLangObj) { currentSql.setText(SQLStringVisitor.getSQLString(theLangObj)); } protected void setEditorLanguageObject(LanguageObject theEditorLangObj) { getEditor().setLanguageObject(savedSelection); if (!editor.isEnabled()) { editor.setEnabled(true); } } protected void setEnabledStatus() { // // set enabled status of delete button // boolean canDelete = treeViewer.canDeleteSelection(); if (canDelete) { if (!deleteAction.isEnabled()) { deleteAction.setEnabled(true); } } else { if (deleteAction.isEnabled()) { deleteAction.setEnabled(false); } } // // set enabled status of OK button // Button btnOk = getButton(OK); boolean enable = treeViewer.isComplete(); if (btnOk.isEnabled() != enable) { btnOk.setEnabled(enable); } } public void setLanguageObject(LanguageObject theLangObj) { // language object must be cloned here so that the original isn't modified. // this prevents the original from being modified even if the user cancels out of the builder. LanguageObject langObj = (theLangObj == null) ? null : (LanguageObject) theLangObj.clone(); savedLangObj = langObj; setOriginalSql(langObj); setCurrentSql(langObj); treeViewer.setLanguageObject(langObj); treeViewer.selectRoot(); treeViewer.expandAll(); // Defect 22003 - needed a context for the original expression // Providing a Lable at the top of the dialog. String labelText = Util.getString(PREFIX + "initialExpression") + //$NON-NLS-1$ CoreStringUtil.Constants.DBL_SPACE + CoreStringUtil.Constants.DBL_SPACE + Util.getString(PREFIX + "undefined"); // $NON-NLS-1$ if (savedLangObj != null) { String loString = savedLangObj.toString(); if (loString.length() > 50) { loString = loString.substring(0, 50) + "..."; // $NON-NLS-1$ } labelText = Util.getString(PREFIX + "initialExpression") + //$NON-NLS-1$ CoreStringUtil.Constants.DBL_SPACE + CoreStringUtil.Constants.DBL_SPACE + loString; } if (originalLanguageObjLabel != null) { originalLanguageObjLabel.setText(labelText); originalLanguageObjLabel.getParent().layout(); } // select root tree node Display.getDefault() .asyncExec( new Runnable() { public void run() { treeViewer.selectRoot(); } }); } protected void setOriginalSql(LanguageObject theLangObj) { originalSql.setText(SQLStringVisitor.getSQLString(theLangObj)); } }
/** * Implements the SourceHandler interface which provides the VDB Editor the ability to access * DQP-related connection info. */ public class VdbSourceConnectionHandler implements SourceHandler { static final String PREFIX = I18nUtil.getPropertyPrefix(VdbSourceConnectionHandler.class); private static SelectTranslatorAction selectTranslatorAction; private static SelectJndiDataSourceAction selectJndiDataSourceAction; private static Object[] actions; private static boolean initialized = false; static String getString(final String stringId) { return UTIL.getString(PREFIX + stringId); } @Override public VdbSourceConnection ensureVdbSourceConnection( String sourceModelname, Properties properties) throws Exception { CoreArgCheck.isNotNull(properties, "properties"); // $NON-NLS-1$ ModelConnectionMapper mapper = new ModelConnectionMapper(sourceModelname, properties); VdbSourceConnection vdbSourceConnection = null; ExecutionAdmin defaultAdmin = getDefaultServer().getAdmin(); String uuid = ModelerCore.workspaceUuid().toString(); try { vdbSourceConnection = mapper.getVdbSourceConnection(defaultAdmin, uuid); } catch (ModelWorkspaceException e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.Error_could_not_find_source_connection_info_for_{0}_model", sourceModelname)); //$NON-NLS-1$ } // TODO: vdbSourceConnection may be NULL, so query the user for translator name & jndi name return vdbSourceConnection; } @Override public Object[] getApplicableActions(Object obj) { if (!initialized) { initialize(); } Server defServer = getDefaultServer(); if (defServer == null || !defServer.isConnected()) { return null; } if (obj instanceof IStructuredSelection) { IStructuredSelection sel = (IStructuredSelection) obj; if (sel.getFirstElement() instanceof VdbModelEntry) { if (((VdbModelEntry) sel.getFirstElement()).getType() == ModelType.PHYSICAL_LITERAL) { selectTranslatorAction.setSelection((VdbModelEntry) sel.getFirstElement()); selectJndiDataSourceAction.setSelection((VdbModelEntry) sel.getFirstElement()); return actions; } } } selectTranslatorAction.setSelection(null); selectJndiDataSourceAction.setSelection(null); return null; } private void initialize() { // Construct the two actions selectTranslatorAction = new SelectTranslatorAction(getString("selectTranslatorAction.label")); // $NON-NLS-1$ selectJndiDataSourceAction = new SelectJndiDataSourceAction( getString("selectJndiDataSourceAction.label")); // $NON-NLS-1$ Collection<IAction> actionsList = new ArrayList(); actionsList.add(selectTranslatorAction); actionsList.add(selectJndiDataSourceAction); actions = actionsList.toArray(); } class SelectJndiDataSourceAction extends Action { public SelectJndiDataSourceAction(String text) { super(text); // TODO Auto-generated constructor stub } private VdbModelEntry vdbModelEntry; public void setSelection(VdbModelEntry vdbModelEntry) { this.vdbModelEntry = vdbModelEntry; } @Override public void run() { // Get available servers and launch SelectTranslatorDialog // vdbModelEntry should not be null and should be a Physical model only if (vdbModelEntry != null) { String jndiName = vdbModelEntry.getJndiName(); SelectJndiDataSourceDialog dialog = new SelectJndiDataSourceDialog(Display.getCurrent().getActiveShell()); TeiidDataSource initialSelection = null; Server defServer = getDefaultServer(); if (defServer != null && defServer.isConnected()) { try { initialSelection = defServer.getAdmin().getDataSource(jndiName); } catch (Exception e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.Error_could_not_find_data_source_for_name", jndiName)); //$NON-NLS-1$ } dialog.setInitialSelection(initialSelection); } dialog.open(); if (dialog.getReturnCode() == Window.OK) { Object result = dialog.getFirstResult(); if (result != null && result instanceof TeiidDataSource) { vdbModelEntry.setJndiName(((TeiidDataSource) result).getName()); } } } } } class SelectTranslatorAction extends Action { public SelectTranslatorAction(String text) { super(text); // TODO Auto-generated constructor stub } private VdbModelEntry vdbModelEntry; public void setSelection(VdbModelEntry vdbModelEntry) { this.vdbModelEntry = vdbModelEntry; } @Override public void run() { // Get available servers and launch SelectTranslatorDialog // vdbModelEntry should not be null and should be a Physical model only if (vdbModelEntry != null) { String transName = vdbModelEntry.getTranslator(); SelectTranslatorDialog dialog = new SelectTranslatorDialog(Display.getCurrent().getActiveShell()); TeiidTranslator initialSelection = null; Server defServer = getDefaultServer(); if (defServer != null && defServer.isConnected()) { try { initialSelection = defServer.getAdmin().getTranslator(transName); } catch (Exception e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.Error_could_not_find_translator_for_name", transName)); //$NON-NLS-1$ } dialog.setInitialSelection(initialSelection); } dialog.open(); if (dialog.getReturnCode() == Window.OK) { Object result = dialog.getFirstResult(); if (result != null && result instanceof TeiidTranslator) { vdbModelEntry.setTranslator(((TeiidTranslator) result).getName()); } } } } } /** * {@inheritDoc} * * @see org.teiid.designer.vdb.connections.SourceHandler#getDataSourceNames() */ @Override public String[] getDataSourceNames() { Server defaultServer = getDefaultServer(); if ((defaultServer != null) && defaultServer.isConnected()) { Collection<TeiidDataSource> dataSources = null; try { dataSources = defaultServer.getAdmin().getDataSources(); } catch (Exception e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.errorObtainingDataSources", defaultServer.getHost())); // $NON-NLS-1$ } if (dataSources != null) { Collection<String> dataSourceNames = new ArrayList<String>(); for (TeiidDataSource dataSource : dataSources) { if (!dataSource.isPreview()) { dataSourceNames.add(dataSource.getName()); } } return dataSourceNames.toArray(new String[dataSourceNames.size()]); } } return null; } Server getDefaultServer() { return DqpPlugin.getInstance().getServerManager().getDefaultServer(); } /** * {@inheritDoc} * * @see * org.teiid.designer.vdb.connections.SourceHandler#getTranslatorDefinitions(java.lang.String) */ @Override public PropertyDefinition[] getTranslatorDefinitions(String translatorName) { if (StringUtilities.isEmpty(translatorName)) { throw new IllegalArgumentException(); } Server defaultServer = getDefaultServer(); if ((defaultServer != null) && defaultServer.isConnected()) { try { TeiidTranslator translator = defaultServer.getAdmin().getTranslator(translatorName); if (translator != null) { Collection<PropertyDefinition> props = new ArrayList<PropertyDefinition>(); for (org.teiid.adminapi.PropertyDefinition propDefn : translator.getPropertyDefinitions()) { TranslatorProperty prop = new TranslatorProperty(propDefn.getPropertyTypeClassName()); prop.advanced = propDefn.isAdvanced(); prop.description = propDefn.getDescription(); prop.displayName = propDefn.getDisplayName(); prop.id = propDefn.getName(); prop.masked = propDefn.isMasked(); prop.modifiable = propDefn.isModifiable(); prop.required = propDefn.isRequired(); prop.defaultValue = (propDefn.getDefaultValue() == null) ? StringUtilities.EMPTY_STRING : propDefn.getDefaultValue().toString(); if (propDefn.isConstrainedToAllowedValues()) { Collection values = propDefn.getAllowedValues(); prop.allowedValues = new String[values.size()]; int i = 0; for (Object value : values) { prop.allowedValues[i++] = value.toString(); } } else { // if boolean type turn into allowed values String type = propDefn.getPropertyTypeClassName(); if (Boolean.class.getName().equals(type) || Boolean.TYPE.getName().equals(type)) { prop.allowedValues = new String[] {Boolean.TRUE.toString(), Boolean.FALSE.toString()}; } } props.add(prop); } return props.toArray(new PropertyDefinition[props.size()]); } } catch (Exception e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.errorObtainingTranslatorProperties", //$NON-NLS-1$ translatorName, defaultServer.getHost())); } } return null; } /** * {@inheritDoc} * * @see org.teiid.designer.vdb.connections.SourceHandler#getTranslatorTypes() */ @Override public String[] getTranslatorTypes() { Server defaultServer = getDefaultServer(); if ((defaultServer != null) && defaultServer.isConnected()) { Collection<TeiidTranslator> translators = null; try { translators = defaultServer.getAdmin().getTranslators(); } catch (Exception e) { UTIL.log( IStatus.ERROR, e, UTIL.getString( "VdbSourceConnectionHandler.errorObtainingTranslators", defaultServer.getHost())); // $NON-NLS-1$ } if (translators != null) { Collection<String> translatorTypes = new ArrayList<String>(); for (TeiidTranslator translator : translators) { translatorTypes.add(translator.getName()); } return translatorTypes.toArray(new String[translatorTypes.size()]); } } return null; } class TranslatorProperty implements PropertyDefinition { private final String className; boolean advanced; String[] allowedValues; String defaultValue; String description; String displayName; String id; boolean masked; boolean modifiable; boolean required; public TranslatorProperty(String className) { this.className = className; } /** * {@inheritDoc} * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if ((obj == null) || (getClass() != obj.getClass())) { return false; } return this.id.equals(((TranslatorProperty) obj).id); } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#getAllowedValues() */ @Override public String[] getAllowedValues() { return this.allowedValues; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#getDefaultValue() */ @Override public String getDefaultValue() { return this.defaultValue; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#getDescription() */ @Override public String getDescription() { return this.description; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#getDisplayName() */ @Override public String getDisplayName() { return this.displayName; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#getId() */ @Override public String getId() { return this.id; } /** * {@inheritDoc} * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return this.id.hashCode(); } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#isAdvanced() */ @Override public boolean isAdvanced() { return this.advanced; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#isMasked() */ @Override public boolean isMasked() { return this.masked; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#isModifiable() */ @Override public boolean isModifiable() { return this.modifiable; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#isRequired() */ @Override public boolean isRequired() { return this.required; } /** * {@inheritDoc} * * @see org.teiid.designer.core.properties.PropertyDefinition#isValidValue(java.lang.String) */ @Override public String isValidValue(String newValue) { // if empty must have a value or a default value if required if (StringUtilities.isEmpty(newValue)) { // invalid if required and no default value if (isRequired() && StringUtilities.isEmpty(getDefaultValue())) { return Util.getString("invalidNullPropertyValue", getDisplayName()); // $NON-NLS-1$ } // OK to be null/empty return null; } if (Boolean.class.getName().equals(this.className) || Boolean.TYPE.getName().equals(this.className)) { if (!newValue.equalsIgnoreCase(Boolean.TRUE.toString()) && !newValue.equalsIgnoreCase(Boolean.FALSE.toString())) { return Util.getString( "invalidPropertyValueForType", newValue, Boolean.TYPE.getName()); // $NON-NLS-1$ } } else if (Character.class.getName().equals(this.className) || Character.TYPE.getName().equals(this.className)) { if (newValue.length() != 1) { return Util.getString( "invalidPropertyValueForType", newValue, Character.TYPE.getName()); // $NON-NLS-1$ } } else if (Byte.class.getName().equals(this.className) || Byte.TYPE.getName().equals(this.className)) { try { Byte.parseByte(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Byte.TYPE.getName()); // $NON-NLS-1$ } } else if (Short.class.getName().equals(this.className) || Short.TYPE.getName().equals(this.className)) { try { Short.parseShort(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Short.TYPE.getName()); // $NON-NLS-1$ } } else if (Integer.class.getName().equals(this.className) || Integer.TYPE.getName().equals(this.className)) { try { Integer.parseInt(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Integer.TYPE.getName()); // $NON-NLS-1$ } } else if (Long.class.getName().equals(this.className) || Long.TYPE.getName().equals(this.className)) { try { Long.parseLong(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Long.TYPE.getName()); // $NON-NLS-1$ } } else if (Float.class.getName().equals(this.className) || Float.TYPE.getName().equals(this.className)) { try { Float.parseFloat(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Float.TYPE.getName()); // $NON-NLS-1$ } } else if (Double.class.getName().equals(this.className) || Double.TYPE.getName().equals(this.className)) { try { Double.parseDouble(newValue); } catch (Exception e) { return Util.getString( "invalidPropertyValueForType", newValue, Double.TYPE.getName()); // $NON-NLS-1$ } } else if (!String.class.getName().equals(this.className)) { return Util.getString( "unknownPropertyType", this.displayName, this.className); // $NON-NLS-1$ } // valid value return null; } } }
/** ElementEditor */ public class ElementEditor extends AbstractLanguageObjectEditor { private static final String PREFIX = I18nUtil.getPropertyPrefix(ElementEditor.class); private ViewController controller; private ElementEditorModel model; private ICriteriaStrategy strategy; private Composite pnlContent; private TreeViewer viewer; /** * Constructs a <code>ElementEditor</code> using the given model. * * @param theParent the parent container * @param theModel the editor's model * @throws IllegalArgumentException if any of the parameters are <code>null</code> */ public ElementEditor(Composite theParent, ElementEditorModel theModel) { super(theParent, ElementSymbol.class, theModel); controller = new ViewController(); model = theModel; model.addModelListener(controller); // set the viewer on the CriteriaStrategy strategy = ElementViewerFactory.getCriteriaStrategy(viewer); strategy.setTreeViewer(viewer); } /** @see com.metamatrix.modeler.transformation.ui.builder.ILanguageObjectEditor#acceptFocus() */ @Override public void acceptFocus() { viewer.getTree().setFocus(); } /** * @see * com.metamatrix.modeler.transformation.ui.builder.AbstractLanguageObjectEditor#createUi(org.eclipse.swt.widgets.Composite) */ @Override protected void createUi(Composite theParent) { pnlContent = new Composite(theParent, SWT.NONE); pnlContent.setLayoutData(new GridData(GridData.FILL_BOTH)); pnlContent.setLayout(new FillLayout()); // // pnlContent contents // viewer = ElementViewerFactory.createElementViewer(pnlContent); viewer.addDoubleClickListener( new IDoubleClickListener() { public void doubleClick(DoubleClickEvent theEvent) { handleDoubleClick(); } }); viewer.addSelectionChangedListener( new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent theEvent) { handleTreeSelection(); } }); viewer.expandAll(); } /** Displays the appropriate UI for the current model state. */ void displayElementSymbol() { CoreArgCheck.isNotNull(viewer); StructuredSelection selection = StructuredSelection.EMPTY; if (model.getElementSymbol() != null) { strategy.setTreeViewer(viewer); // make sure this viewer is set before using strategy Object node = strategy.getNode(model.getElementSymbol()); if (node != null) { selection = new StructuredSelection(node); } if (!selection.equals(viewer.getSelection())) { viewer.setSelection(selection); } } } /** @see com.metamatrix.modeler.transformation.ui.builder.ILanguageObjectEditor#getTitle() */ @Override public String getTitle() { return Util.getString(PREFIX + "title"); // $NON-NLS-1$ } /** * @see * com.metamatrix.modeler.transformation.ui.builder.AbstractLanguageObjectEditor#getToolTipText() */ @Override public String getToolTipText() { return Util.getString(PREFIX + "tip"); // $NON-NLS-1$ } /** Handler for double-click in tree. */ void handleDoubleClick() {} /** Handler for tree selection. */ void handleTreeSelection() { IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); ElementSymbol element = null; if (!selection.isEmpty()) { ICriteriaStrategy strategy = ElementViewerFactory.getCriteriaStrategy(viewer); strategy.setTreeViewer(viewer); // make sure this viewer is set before using strategy if (strategy.isValid(selection.getFirstElement())) { Object eObj = selection.getFirstElement(); if (eObj instanceof ElementSymbol) { element = ((ElementSymbol) eObj); } else { element = new ElementSymbol(strategy.getRuntimeFullName(eObj), true); // the viewer model contains EObjects. so the objects in the selection will // be EObjects. since the EObject is used later on in the QueryCriteriaStrategy.getNode() // method. save it here. element.setMetadataID(eObj); } } } model.selectElementSymbol(element); } /** * @see * com.metamatrix.modeler.transformation.ui.builder.ILanguageObjectEditor#setLanguageObject(com.metamatrix.query.sql.LanguageObject) */ @Override public void setLanguageObject(LanguageObject theLanguageObject) { if (theLanguageObject == null) { clear(); } else { if (!(theLanguageObject instanceof ElementSymbol)) { CoreArgCheck.isTrue( (theLanguageObject instanceof ElementSymbol), Util.getString( PREFIX + "invalidLanguageObject", // $NON-NLS-1$ new Object[] {theLanguageObject.getClass().getName()})); } model.setLanguageObject(theLanguageObject); } } /** * The <code>ViewController</code> class is a view controller for the <code>ElementEditor</code>. */ class ViewController implements ILanguageObjectEditorModelListener { /** * @see * com.metamatrix.query.internal.ui.builder.model.ILanguageObjectEditorModelListener#modelChanged(com.metamatrix.query.internal.ui.builder.model.LanguageObjectEditorModelEvent) */ public void modelChanged(LanguageObjectEditorModelEvent theEvent) { displayElementSymbol(); } } }