/* * Copyright (c) 2015 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.functions.groovy.internal; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nullable; import org.eclipse.jface.dialogs.DialogTray; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import de.fhg.igd.slf4jplus.ALogger; import de.fhg.igd.slf4jplus.ALoggerFactory; import eu.esdihumboldt.cst.functions.groovy.GroovyConstants; import eu.esdihumboldt.cst.functions.groovy.helper.Category; import eu.esdihumboldt.cst.functions.groovy.helper.HelperFunctionOrCategory; import eu.esdihumboldt.cst.functions.groovy.helper.HelperFunctionsService; import eu.esdihumboldt.cst.functions.groovy.helper.spec.Argument; import eu.esdihumboldt.cst.functions.groovy.helper.spec.impl.HelperFunctionSpecification; import eu.esdihumboldt.hale.ui.HaleUI; import eu.esdihumboldt.hale.ui.HaleWizardPage; import eu.esdihumboldt.hale.ui.common.CommonSharedImages; import eu.esdihumboldt.hale.ui.util.viewer.tree.TreePathFilteredTree; import eu.esdihumboldt.hale.ui.util.viewer.tree.TreePathPatternFilter; import eu.esdihumboldt.hale.ui.util.viewer.tree.TreePathProviderAdapter; /** * Tools for helper function dialog page * * @author Sameer Sheikh */ public class PageFunctions extends DialogTray implements GroovyConstants { private static final AtomicBoolean BROWSER_ERROR_REPORTED = new AtomicBoolean(); private static final ALogger log = ALoggerFactory.getLogger(PageFunctions.class); private static final String TAB_SPACE = "    "; private Text textField; private Browser browser = null; /** * Creates a tool item for a helper function dialog page * * @param toolbar the tool bar * @param page the dialog page */ public static void createToolItem(ToolBar toolbar, final HaleWizardPage<?> page) { ToolItem item = new ToolItem(toolbar, SWT.PUSH); item.setToolTipText("Show functions"); item.setImage(CommonSharedImages.getImageRegistry().get(CommonSharedImages.IMG_FUNCTION)); item.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { if (page.getContainer() instanceof TrayDialog) { TrayDialog tray = (TrayDialog) page.getContainer(); if (tray.getTray() != null) { tray.closeTray(); } tray.openTray(new PageFunctions()); } } @Override public void widgetDefaultSelected(SelectionEvent e) { // do nothing } }); } /** * @see org.eclipse.jface.dialogs.DialogTray#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { Composite comp = new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(comp); Label label = new Label(comp, SWT.NONE); label.setText("Functions Overview"); label.setFont(JFaceResources.getHeaderFont()); // tree viwever PatternFilter patternFilter = new TreePathPatternFilter(); patternFilter.setIncludeLeadingWildcard(true); final FilteredTree filteredTree = new TreePathFilteredTree(comp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, patternFilter, true); TreeViewer tree = filteredTree.getViewer(); tree.setUseHashlookup(true); HelperFunctionLabelProvider labelProvider = new HelperFunctionLabelProvider(); tree.setLabelProvider(labelProvider); IContentProvider contentProvider; HelperFunctionsService functions = HaleUI.getServiceProvider() .getService(HelperFunctionsService.class); contentProvider = new TreePathProviderAdapter(new HelperFunctionContentProvider(functions)); tree.setContentProvider(contentProvider); GridDataFactory.fillDefaults().grab(true, true).hint(280, 400).applyTo(filteredTree); tree.setComparator(new HelperFunctionComparator()); tree.setInput(Category.ROOT); // Examples Label example = new Label(comp, SWT.NONE); example.setText("Function documentation"); try { browser = new Browser(comp, SWT.WRAP | SWT.BORDER); browser.setLayoutData( GridDataFactory.fillDefaults().grab(true, true).hint(300, 250).create()); } catch (Throwable e) { if (BROWSER_ERROR_REPORTED.compareAndSet(false, true)) { log.error("Could not create embedded browser, using text field as fall-back", e); } textField = new Text(comp, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL); textField.setLayoutData( GridDataFactory.fillDefaults().grab(true, true).hint(300, 250).create()); } tree.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { String eg = null; HelperFunctionSpecification hfs = null; if (!event.getSelection().isEmpty()) { TreeSelection treesel = (TreeSelection) event.getSelection(); TreePath[] paths = treesel.getPaths(); if (paths != null) { TreePath path = paths[0]; for (int i = 0; i < path.getSegmentCount(); i++) { if (path.getSegment(i) instanceof Category) { eg = "Select a function to see its documentation."; if (browser != null) { browser.setText(eg); } else if (textField != null) { textField.setText(eg); } } else if (path.getSegment(i) instanceof HelperFunctionOrCategory) { HelperFunctionOrCategory hfoc = ((HelperFunctionOrCategory) path .getSegment(i)); try { hfs = (HelperFunctionSpecification) hfoc.asFunction() .getSpec(hfoc.getName()); } catch (Exception e) { log.error( "There is a problem in retrieving the specification for a helper function.", e); } // displaying the specification if (browser != null) { eg = getFunctionSpecHTML(hfs); browser.setText(eg); } else if (textField != null) { eg = getFunctionSpecText(hfs); textField.setText(eg); } } } } } } }); return comp; } /** * get the specification of a given function * * @param spec helper function specification * @return the specification text display for a helper function. * */ private String getFunctionSpecText(HelperFunctionSpecification spec) { StringBuilder example = new StringBuilder(); // example.append("Description:"); // example.append("\n\t"); example.append(spec.getDescription()); example.append(" \n\nParameters: "); for (Argument arg : spec.getArguments()) { example.append("\n \t"); example.append(arg.getName()); example.append(": "); example.append(arg.getDescription()); if (getDefaultValueToDisplay(arg) != null) { example.append(" - "); example.append("default value: "); example.append(getDefaultValueToDisplay(arg) + " (" + arg.getDefaultValue().getClass().getSimpleName() + ")"); } } example.append("\n\nReturns: \n"); example.append("\t"); example.append(spec.getResultDescription()); return example.toString(); } /** * Returns a HTML string representing the additional information of a * function. * * @param hfs Helper function specification for a function * @return additional message in HTML string */ public static String getFunctionSpecHTML(HelperFunctionSpecification hfs) { StringBuilder example = new StringBuilder("<div>"); // example.append(" <H3>Description:</H3> "); // example.append(TAB_SPACE); example.append(hfs.getDescription()); example.append("<br><br><h3>Parameters:</h3>"); for (Argument arg : hfs.getArguments()) { example.append("<b>"); example.append(TAB_SPACE + arg.getName()); example.append("</b>"); example.append(": "); example.append(arg.getDescription()); if (getDefaultValueToDisplay(arg) != null) example.append(" - default value: " + getDefaultValueToDisplay(arg) + " (" + arg.getDefaultValue().getClass().getSimpleName() + ")"); example.append("<br>"); } example.append("<br><h3>Returns: </h3>"); example.append(TAB_SPACE + hfs.getResultDescription()); example.append("</div>"); return example.toString(); } @Nullable private static String getDefaultValueToDisplay(Argument arg) { Object defaultValue = arg.getDefaultValue(); if (defaultValue instanceof Number || defaultValue instanceof Boolean) { return String.valueOf(defaultValue); } else if (defaultValue instanceof String) { return "'" + defaultValue + "'"; } return null; } /** * * Gets formatted parameters of a function as a String with parameters * separated by comma * * @param hfs Helper function specification * @return the formated parameters as string separated by comma */ public static StyledString getStyledParameters(HelperFunctionSpecification hfs) { StyledString s = new StyledString(); int argSize = hfs.getArguments().size(); s.append("(", StyledString.DECORATIONS_STYLER); Iterator<Argument> x = hfs.getArguments().iterator(); if (x.hasNext()) { Argument arg = x.next(); s.append(arg.getName(), StyledString.DECORATIONS_STYLER); if (argSize > 1) { s.append(": ", StyledString.DECORATIONS_STYLER); if (getDefaultValueToDisplay(arg) != null) { s.append(getDefaultValueToDisplay(arg), StyledString.COUNTER_STYLER); } else { s.append("?", StyledString.COUNTER_STYLER); } } while (x.hasNext()) { Argument arg1 = x.next(); s.append(", " + arg1.getName(), StyledString.DECORATIONS_STYLER); s.append(": ", StyledString.DECORATIONS_STYLER); if (getDefaultValueToDisplay(arg1) != null) { s.append(getDefaultValueToDisplay(arg1), StyledString.COUNTER_STYLER); } else { s.append("?", StyledString.COUNTER_STYLER); } } } s.append(")", StyledString.DECORATIONS_STYLER); return s; } }