// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package com.amalto.workbench.editors; import java.net.URL; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.ITextListener; import org.eclipse.jface.text.TextEvent; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.VerticalRuler; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetAdapter; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.events.IHyperlinkListener; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Hyperlink; import com.amalto.workbench.actions.EditXObjectAction; import com.amalto.workbench.dialogs.DOMViewDialog; import com.amalto.workbench.dialogs.QueryParametersDialog; import com.amalto.workbench.dialogs.TextViewDialog; import com.amalto.workbench.i18n.Messages; import com.amalto.workbench.image.ImageCache; import com.amalto.workbench.models.TreeObject; import com.amalto.workbench.models.TreeObjectTransfer; import com.amalto.workbench.models.TreeParent; import com.amalto.workbench.providers.XObjectEditorInput; import com.amalto.workbench.service.MissingJarService; import com.amalto.workbench.utils.Util; import com.amalto.workbench.utils.WidgetUtils; import com.amalto.workbench.webservices.TMDMService; import com.amalto.workbench.webservices.WSDataClusterPK; import com.amalto.workbench.webservices.WSExecuteStoredProcedure; import com.amalto.workbench.webservices.WSPutStoredProcedure; import com.amalto.workbench.webservices.WSStoredProcedure; import com.amalto.workbench.webservices.WSStoredProcedurePK; import com.amalto.workbench.webservices.WSStringArray; public class StoredProcedureMainPage extends AMainPage implements ITextListener { private static Log log = LogFactory.getLog(StoredProcedureMainPage.class); protected Text descriptionText; protected SourceViewer procedureViewer; protected TableViewer resultsViewer; protected Combo dataClusterCombo; protected Label resultsLabel; protected LinkedList<String> currentParameters = new LinkedList<String>(); protected boolean refreshing = false; private boolean comitting = false; private Button refreshCacheBtn; private final static String[] KEYWORDS = new String[] { Messages.StoredProcedureMainPage_0, Messages.StoredProcedureMainPage_1, Messages.StoredProcedureMainPage_2 }; public StoredProcedureMainPage(FormEditor editor) { super(editor, StoredProcedureMainPage.class.getName(), Messages.StoredProcedureMainPage_3 + ((XObjectEditorInput) editor.getEditorInput()).getName() + Util.getRevision((TreeObject) ((XObjectEditorInput) editor.getEditorInput()).getModel())); } @Override protected void createCharacteristicsContent(FormToolkit toolkit, Composite charComposite) { try { WSStoredProcedure wsStoredProcedure = (WSStoredProcedure) (getXObject().getWsObject()); // description Label descriptionLabel = toolkit.createLabel(charComposite, Messages.StoredProcedureMainPage_4, SWT.NULL); descriptionLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 1, 1)); descriptionText = toolkit.createText(charComposite, "", SWT.BORDER);//$NON-NLS-1$ descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); descriptionText.setText(wsStoredProcedure.getDescription() == null ? "" : wsStoredProcedure.getDescription());//$NON-NLS-1$ descriptionText.addModifyListener(this); // Procedure Group storedProcedureGroup = new Group(charComposite, SWT.SHADOW_NONE); storedProcedureGroup.setText(Messages.StoredProcedureMainPage_5); storedProcedureGroup.setLayout(new GridLayout(1, true)); storedProcedureGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); ((GridData) storedProcedureGroup.getLayoutData()).minimumHeight = 100; procedureViewer = new SourceViewer(storedProcedureGroup, new VerticalRuler(10), SWT.V_SCROLL); procedureViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); procedureViewer.addTextListener(this); WidgetUtils.initRedoUndo(procedureViewer); refreshCacheBtn = toolkit.createButton(charComposite, Messages.StoredProcedureMainPage_6, SWT.CHECK); refreshCacheBtn.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); refreshCacheBtn.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { markDirty(); } public void widgetDefaultSelected(SelectionEvent e) { markDirty(); } }); /************************************************************ * Execute Stored Procedure ************************************************************/ createCompDropTarget(); Composite resultsGroup = this.getNewSectionComposite(Messages.StoredProcedureMainPage_7); resultsGroup.setLayout(new GridLayout(4, false)); // data cluster Hyperlink dataClusterLink = toolkit.createHyperlink(resultsGroup, Messages.StoredProcedureMainPage_8, SWT.NULL); dataClusterLink.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 1, 1)); dataClusterLink.addHyperlinkListener(new IHyperlinkListener() { public void linkEntered(org.eclipse.ui.forms.events.HyperlinkEvent e) { } public void linkExited(org.eclipse.ui.forms.events.HyperlinkEvent e) { } public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) { if (!isLocalInput()) { TreeParent serverRoot = StoredProcedureMainPage.this.getXObject().getServerRoot(); TreeObject iaObject = new TreeObject(StoredProcedureMainPage.this.dataClusterCombo.getText(), serverRoot, TreeObject.DATA_CLUSTER, new WSDataClusterPK(StoredProcedureMainPage.this.dataClusterCombo .getText()), null); (new EditXObjectAction(iaObject, StoredProcedureMainPage.this.getSite().getPage())).run(); } }; }); dataClusterCombo = new Combo(resultsGroup, SWT.READ_ONLY | SWT.DROP_DOWN | SWT.SINGLE); dataClusterCombo.setLayoutData(new GridData(SWT.BEGINNING, SWT.NONE, false, false, 1, 1)); Button executeButton = new Button(resultsGroup, SWT.PUSH); executeButton.setText(Messages.StoredProcedureMainPage_9); executeButton.addMouseListener(new MouseListener() { public void mouseUp(MouseEvent e) { executeProcedure(); } public void mouseDoubleClick(MouseEvent e) { } public void mouseDown(MouseEvent e) { } }); resultsLabel = toolkit .createLabel( resultsGroup, " ",//$NON-NLS-1$ SWT.NULL); resultsLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 1, 1)); resultsViewer = new TableViewer(resultsGroup); resultsViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1)); ((GridData) resultsViewer.getControl().getLayoutData()).heightHint = 300; resultsViewer.setContentProvider(new ArrayContentProvider()); resultsViewer.setLabelProvider(new XMLTableLabelProvider()); resultsViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { resultsViewer.setSelection(event.getSelection()); new ResultsViewAction(StoredProcedureMainPage.this.getSite().getShell(), resultsViewer).run(); } }); hookContextMenu(); refreshData(); dataClusterCombo.select(0); } catch (Exception e) { log.error(e.getMessage(), e); } }// createCharacteristicsContent @Override protected void refreshData() { if (this.comitting) { return; } this.refreshing = true; WSStoredProcedure wsStoredProcedure = (WSStoredProcedure) (getXObject().getWsObject()); String s; s = wsStoredProcedure.getDescription() == null ? "" : wsStoredProcedure.getDescription();//$NON-NLS-1$ if (!s.equals(descriptionText.getText())) { descriptionText.setText(s); } Document doc = new Document(wsStoredProcedure.getProcedure()); procedureViewer.setDocument(doc); refreshCacheBtn.setSelection(wsStoredProcedure.isRefreshCache() != null && wsStoredProcedure.isRefreshCache() ? true : false); initDataClusterCombo(); this.refreshing = false; } protected void initDataClusterCombo() { dataClusterCombo.removeAll(); List<WSDataClusterPK> dataClusterPKs; try { dataClusterPKs = Util.getAllDataClusterPKs(new URL(getXObject().getEndpointAddress()), getXObject().getUsername(), getXObject().getPassword()); } catch (Exception ex) { MessageDialog.openError( StoredProcedureMainPage.this.getSite().getShell(), Messages._Error, Messages.StoredProcedureMainPage_11 + ex.getClass().getName() + Messages.StoredProcedureMainPage_12 + ex.getLocalizedMessage()); this.refreshing = false; return; } if ((dataClusterPKs == null) || (dataClusterPKs.size() == 0) || ((dataClusterPKs.size() == 1) && ("CACHE".equals(dataClusterPKs.get(0).getPk())))) {//$NON-NLS-1$ MessageDialog.openError(this.getSite().getShell(), Messages._Error, Messages.StoredProcedureMainPage_14); return; } dataClusterCombo.add("[ALL]");//$NON-NLS-1$ for (int i = 0; i < dataClusterPKs.size(); i++) { if (!"CACHE".equals(dataClusterPKs.get(i).getPk())) { dataClusterCombo.add(dataClusterPKs.get(i).getPk()); } } } @Override protected void commit() { if (this.refreshing) { return; } this.comitting = true; WSStoredProcedure wsStoredProcedure = (WSStoredProcedure) (getXObject().getWsObject()); wsStoredProcedure.setDescription(descriptionText.getText()); wsStoredProcedure.setProcedure(procedureViewer.getDocument().get()); wsStoredProcedure.setRefreshCache(refreshCacheBtn.getSelection()); this.comitting = false; } // no specific actions here @Override public void createActions() { return; } public void textChanged(TextEvent event) { if (this.refreshing) { return; } markDirty(); } private void hookContextMenu() { MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { manager.add(new ResultsViewAction(StoredProcedureMainPage.this.getSite().getShell(), StoredProcedureMainPage.this.resultsViewer)); } }); Menu menu = menuMgr.createContextMenu(resultsViewer.getControl()); resultsViewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, resultsViewer); } protected void executeProcedure() { boolean checkMissingJar = MissingJarService.getInstance().checkMissingJar(true); if (!checkMissingJar) { return; } BusyIndicator.showWhile(this.getPartControl().getDisplay(), new Runnable() { public void run() { WSDataClusterPK dcpk = null; if (!"[ALL]".equals(dataClusterCombo.getText())) { dcpk = new WSDataClusterPK(dataClusterCombo.getText()); } try { String proc = procedureViewer.getDocument().get(); // read parameters int number = 0; while (true) { Pattern p = Pattern.compile(".*[^\\\\]%" + number + "[^\\d]*.*", Pattern.DOTALL);//$NON-NLS-1$//$NON-NLS-2$ Matcher m = p.matcher(proc); if (!m.matches()) { break; } else { ++number; } } String[] ps = null; if (number > 0) { // transfer current parameters to new array ps = new String[number]; for (int i = 0; i < number; i++) { if (i < currentParameters.size()) { ps[i] = currentParameters.get(i); } else { ps[i] = "";//$NON-NLS-1$ } } // call parameters window QueryParametersDialog dialog = new QueryParametersDialog(StoredProcedureMainPage.this.getSite() .getShell(), ps); dialog.setBlockOnOpen(true); dialog.open(); if (dialog.getButtonPressed() == QueryParametersDialog.BUTTON_CANCEL) { return; } ps = dialog.getParameters(); // Apply parameters for (int i = 0; i < ps.length; i++) { // transfer parameters back into current parameters if (i < currentParameters.size()) { currentParameters.set(i, ps[i]); } else { currentParameters.add(ps[i]); } } } // perform call TMDMService service = getMDMService(); if (service != null) { WSStoredProcedure wsStoredProcedure = (WSStoredProcedure) (getXObject().getWsObject()); service.putStoredProcedure(new WSPutStoredProcedure(wsStoredProcedure)); WSStringArray array = service.executeStoredProcedure(new WSExecuteStoredProcedure(currentParameters, dcpk, new WSStoredProcedurePK(wsStoredProcedure.getName()))); List<String> results = array.getStrings(); resultsLabel.setText(Messages.StoredProcedureMainPage_15 + results.size() + Messages.StoredProcedureMainPage_16); resultsViewer.setInput(results); } } catch (Exception ex) { if (!Util.handleConnectionException(StoredProcedureMainPage.this.getSite().getShell(), ex, null)) { String message = ex.getMessage(); Set<String> messages = getMessages(message); StringBuilder builder = new StringBuilder(); for (String currentMessage : messages) { builder.append(currentMessage + '\n'); } MessageDialog.openError(StoredProcedureMainPage.this.getSite().getShell(), Messages._Error, builder.toString()); } } } }); } private static Set<String> getMessages(String msg) { StringTokenizer tokenizer = new StringTokenizer(msg, Messages.StoredProcedureMainPage_18); StringBuilder currentMessage = new StringBuilder(); Set<String> messages = new HashSet<String>(); int currentKeywordIndex = 0; while (tokenizer.hasMoreElements()) { String element = tokenizer.nextToken().trim(); if (!element.matches(".*Exception:")) { //$NON-NLS-1$ if (element.equals(KEYWORDS[currentKeywordIndex])) { currentKeywordIndex++; if (currentKeywordIndex == KEYWORDS.length - 1) { String newMessage = currentMessage.toString(); messages.add(newMessage); currentMessage = new StringBuilder(); currentKeywordIndex = 0; } } else { if (!element.equals("is:") && !element.equals("\n;")) { //$NON-NLS-1$ //$NON-NLS-2$ currentMessage.append(element.replace("\n;", "")).append(" "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } } } String newMessage = currentMessage.toString(); messages.add(newMessage); return messages; } class ResultsViewAction extends Action { private Shell shell = null; private Viewer viewer; public ResultsViewAction(Shell shell, Viewer viewer) { super(); this.shell = shell; this.viewer = viewer; setImageDescriptor(ImageCache.getImage("icons/add_obj.gif"));//$NON-NLS-1$ setText(Messages.StoredProcedureMainPage_19); setToolTipText(Messages.StoredProcedureMainPage_20); } @Override public void run() { try { super.run(); IStructuredSelection selection = ((IStructuredSelection) viewer.getSelection()); String result = (String) selection.getFirstElement(); // clean up highlights result = result.replaceAll("\\s*__h", "").replaceAll("h__\\s*", "");//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ // try to parse it try { final DOMViewDialog d = new DOMViewDialog(shell, Util.parse(result)); d.setBlockOnOpen(true); d.addListener(new Listener() { public void handleEvent(Event event) { if (event.button == DOMViewDialog.BUTTON_CLOSE) { d.close(); } } }); d.open(); } catch (Exception e) { // not an XML Dialog d = new TextViewDialog(shell, result); d.setBlockOnOpen(true); d.open(); } } catch (Exception e) { log.error(e.getMessage(), e); MessageDialog.openError(shell, Messages._Error, Messages.StoredProcedureMainPage_22 + e.getLocalizedMessage()); } } @Override public void runWithEvent(Event event) { super.runWithEvent(event); } } protected static Pattern highlightLeft = Pattern.compile("\\s*__h");//$NON-NLS-1$ protected static Pattern highlightRight = Pattern.compile("h__\\s*");//$NON-NLS-1$ protected static Pattern emptyTags = Pattern.compile("\\s*<(.*?)\\/>\\s*");//$NON-NLS-1$ protected static Pattern openingTags = Pattern.compile("\\s*<([^\\/].*?[^\\/])>\\s*");//$NON-NLS-1$ protected static Pattern closingTags = Pattern.compile("\\s*</(.*?)>\\s*");//$NON-NLS-1$ class XMLTableLabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { String xml = (String) element; xml = highlightLeft.matcher(xml).replaceAll("");//$NON-NLS-1$ xml = highlightRight.matcher(xml).replaceAll("");//$NON-NLS-1$ xml = emptyTags.matcher(xml).replaceAll("[$1]");//$NON-NLS-1$ xml = openingTags.matcher(xml).replaceAll("[$1: ");//$NON-NLS-1$ xml = closingTags.matcher(xml).replaceAll("]");//$NON-NLS-1$ if (xml.length() >= 150) { return xml.substring(0, 150) + "...";//$NON-NLS-1$ } return xml; } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } private void createCompDropTarget() { DropTarget dropTarget = new DropTarget(procedureViewer.getTextWidget(), DND.DROP_MOVE | DND.DROP_LINK); dropTarget.setTransfer(new TreeObjectTransfer[] { TreeObjectTransfer.getInstance() }); dropTarget.addDropListener(new DropTargetAdapter() { @Override public void dragEnter(DropTargetEvent event) { } @Override public void dragLeave(DropTargetEvent event) { } @Override public void dragOver(DropTargetEvent event) { event.feedback |= DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL; } @Override public void drop(DropTargetEvent event) { if (event.data instanceof TreeObject[]) { procedureViewer.getTextWidget().setText( procedureViewer.getTextWidget().getText() + ((TreeObject[]) event.data)[0].getDisplayName()); } } }); } }