/* * uDig - User Friendly Desktop Internet GIS client * (C) MangoSystem - www.mangosystem.com * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD * License v1.0 (http://udig.refractions.net/files/bsd3-v10.html). */ package org.locationtech.udig.processingtoolbox.internal.ui; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.data.Parameter; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.feature.FeatureCollection; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.process.ProcessFactory; import org.geotools.process.spatialstatistics.core.Params; import org.geotools.util.logging.Logging; import org.locationtech.udig.processingtoolbox.ToolboxPlugin; import org.locationtech.udig.processingtoolbox.ToolboxView; import org.locationtech.udig.processingtoolbox.internal.Messages; import org.locationtech.udig.processingtoolbox.internal.ui.OutputDataWidget.FileDataType; import org.locationtech.udig.processingtoolbox.styler.MapUtils; import org.locationtech.udig.processingtoolbox.styler.ProcessExecutorOperation; import org.locationtech.udig.processingtoolbox.tools.HtmlWriter; import org.locationtech.udig.project.IMap; import org.locationtech.udig.project.ui.internal.LayersView; import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import org.opengis.filter.expression.Expression; import org.opengis.geometry.BoundingBox; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Geometry; /** * Process Execution Dialog * * @author Minpa Lee, MangoSystem * * @source $URL$ */ public class ProcessExecutionDialog extends TitleAreaDialog { protected static final Logger LOGGER = Logging.getLogger(ProcessExecutionDialog.class); private IMap map; private org.geotools.process.ProcessFactory factory; private org.opengis.feature.type.Name processName; private String windowTitle; private Map<String, Object> inputParams = new HashMap<String, Object>(); private Map<String, Object> outputParams = new HashMap<String, Object>(); private Map<Widget, Map<String, Object>> uiParams = new HashMap<Widget, Map<String, Object>>(); private boolean outputTabRequired = false; private int height = 100; private int scale = 1; private Browser browser; private CTabItem inputTab, outputTab; public ProcessExecutionDialog(Shell parentShell, IMap map, ProcessFactory factory, Name processName) { super(parentShell); setShellStyle(SWT.CLOSE | SWT.MIN | SWT.TITLE | SWT.BORDER | SWT.MODELESS | SWT.RESIZE); this.map = map; this.factory = factory; this.processName = processName; this.windowTitle = factory.getTitle(processName).toString(); this.scale = (int) parentShell.getDisplay().getDPI().x / 96; } @Override public void create() { super.create(); setTitle(getShell().getText()); setMessage(factory.getDescription(processName).toString()); } @Override protected Point getInitialSize() { return new org.eclipse.swt.graphics.Point(650 * scale, height); } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText(windowTitle); } @Override protected Control createDialogArea(final Composite parent) { Composite area = (Composite) super.createDialogArea(parent); // 0. Tab Folder final CTabFolder parentTabFolder = new CTabFolder(area, SWT.BOTTOM); parentTabFolder.setUnselectedCloseVisible(false); parentTabFolder.setLayout(new FillLayout()); parentTabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // 1. Process execution inputTab = createInputTab(parentTabFolder); // 2. Simple output if (outputTabRequired) { outputTab = createOutputTab(parentTabFolder); } // 3. Help createHelpTab(parentTabFolder); parentTabFolder.setSelection(inputTab); // set maximum height area.pack(); parentTabFolder.pack(); int maxHeight = 500 * scale; height = parent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y + (150 * scale); height = height > maxHeight ? maxHeight : height; return area; } private CTabItem createOutputTab(final CTabFolder parentTabFolder) { CTabItem tab = new CTabItem(parentTabFolder, SWT.NONE); tab.setText(Messages.ProcessExecutionDialog_taboutput); try { browser = new Browser(parentTabFolder, SWT.NONE); GridData layoutData = new GridData(GridData.FILL_BOTH); browser.setLayoutData(layoutData); tab.setControl(browser); } catch (Exception e) { LOGGER.log(Level.WARNING, e.getMessage(), e); } return tab; } private CTabItem createHelpTab(final CTabFolder parentTabFolder) { CTabItem tab = new CTabItem(parentTabFolder, SWT.NONE); tab.setText(Messages.ProcessExecutionDialog_tabhelp); try { Browser browser = new Browser(parentTabFolder, SWT.NONE); GridData layoutData = new GridData(GridData.FILL_BOTH); browser.setLayoutData(layoutData); HtmlWriter writer = new HtmlWriter(windowTitle); writer.writeProcessMetadata(factory, processName); browser.setText(writer.getHTML()); tab.setControl(browser); } catch (Exception e) { LOGGER.log(Level.WARNING, e.getMessage(), e); } return tab; } private CTabItem createInputTab(final CTabFolder parentTabFolder) { CTabItem tab = new CTabItem(parentTabFolder, SWT.NONE); tab.setText(Messages.ProcessExecutionDialog_tabparameters); ScrolledComposite scroller = new ScrolledComposite(parentTabFolder, SWT.NONE | SWT.V_SCROLL | SWT.H_SCROLL); scroller.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite container = new Composite(scroller, SWT.NONE); container.setLayout(new GridLayout(1, false)); container.setLayoutData(new GridData(GridData.FILL_BOTH)); // input parameters Map<String, Parameter<?>> paramInfo = factory.getParameterInfo(processName); for (Entry<String, Parameter<?>> entrySet : paramInfo.entrySet()) { if (ToolboxView.getMandatoryParameterOnly() && entrySet.getValue().getMinOccurs() == 0) { continue; } inputParams.put(entrySet.getValue().key, entrySet.getValue().sample); insertControl(container, entrySet.getValue()); } // output location Map<String, Parameter<?>> resultInfo = factory.getResultInfo(processName, null); final int outputCnt = resultInfo.size(); for (Entry<String, Parameter<?>> entrySet : resultInfo.entrySet()) { Class<?> binding = entrySet.getValue().type; boolean outputWidgetRequired = false; FileDataType fileDataType = FileDataType.SHAPEFILE; if (SimpleFeatureCollection.class.isAssignableFrom(binding)) { outputWidgetRequired = true; fileDataType = FileDataType.SHAPEFILE; } else if (Geometry.class.isAssignableFrom(binding)) { outputWidgetRequired = true; fileDataType = FileDataType.SHAPEFILE; } else if (ReferencedEnvelope.class.isAssignableFrom(binding)) { outputWidgetRequired = true; fileDataType = FileDataType.SHAPEFILE; } else if (BoundingBox.class.isAssignableFrom(binding)) { outputWidgetRequired = true; fileDataType = FileDataType.SHAPEFILE; } else if (GridCoverage2D.class.isAssignableFrom(binding)) { outputWidgetRequired = true; fileDataType = FileDataType.RASTER; } else { outputTabRequired = true; } if (outputWidgetRequired) { outputParams.put(entrySet.getValue().key, entrySet.getValue().sample); OutputLocationWidget view = new OutputLocationWidget(fileDataType, SWT.SAVE); view.create(container, SWT.BORDER, outputParams, entrySet.getValue()); if (outputCnt > 1) { view.setOutputName(entrySet.getKey()); } else { view.setOutputName(processName.getLocalPart().toLowerCase()); } } } scroller.setContent(container); tab.setControl(scroller); scroller.pack(); container.pack(); scroller.setMinSize(450, container.getSize().y - 2); scroller.setExpandVertical(true); scroller.setExpandHorizontal(true); return tab; } private void insertParamTitle(Composite container, final Parameter<?> param) { String postfix = ""; //$NON-NLS-1$ if (param.type.isAssignableFrom(Geometry.class)) { postfix = "(WKT)"; //$NON-NLS-1$ } // capitalize title String title = param.title.toString(); title = Character.toUpperCase(title.charAt(0)) + title.substring(1); CLabel lblName = new CLabel(container, SWT.NONE); lblName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1)); FontData[] fontData = lblName.getFont().getFontData(); for (int i = 0; i < fontData.length; ++i) { fontData[i].setStyle(SWT.NORMAL); } lblName.setFont(new Font(container.getDisplay(), fontData)); if (param.required) { Image image = ToolboxPlugin.getImageDescriptor("icons/public_co.gif").createImage(); //$NON-NLS-1$ lblName.setImage(image); lblName.setText(title + postfix); } else { lblName.setText(title + Messages.ProcessExecutionDialog_optional + postfix); } lblName.setToolTipText(param.description.toString()); } private void insertControl(Composite container, final Parameter<?> param) { // process name insertParamTitle(container, param); // process value if (param.maxOccurs > 1) { if (SimpleFeatureCollection.class.isAssignableFrom(param.type) || FeatureCollection.class.isAssignableFrom(param.type)) { // vector layers parameters FeatureCollectionsDataWidget featuresView = new FeatureCollectionsDataWidget(map); featuresView.create(container, SWT.NONE, inputParams, param); } else if (GridCoverage2D.class.isAssignableFrom(param.type)) { // raster layers parameters GridCoveragesDataWidget gridCoverageView = new GridCoveragesDataWidget(map); gridCoverageView.create(container, SWT.NONE, inputParams, param); } else if (Geometry.class.isAssignableFrom(param.type)) { // wkt geometries parameters GeometryWidget geometryView = new GeometryWidget(map); geometryView.create(container, SWT.NONE, inputParams, param); } else { Map<String, Object> metadata = param.metadata; if (metadata == null || metadata.size() == 0) { // other literal parameters LiteralDataWidget literalView = new LiteralDataWidget(map); literalView.create(container, SWT.NONE, inputParams, param); } else { if (metadata.containsKey(Params.FIELD)) { LiteralDataFieldWidget fieldView = new LiteralDataFieldWidget(map); fieldView.create(container, SWT.NONE, inputParams, param, uiParams); } else if (metadata.containsKey(Params.FIELDS)) { LiteralDataFieldsWidget fieldView = new LiteralDataFieldsWidget(map); fieldView.create(container, SWT.NONE, inputParams, param, uiParams); } else { // other literal parameters LiteralDataWidget literalView = new LiteralDataWidget(map); literalView.create(container, SWT.NONE, inputParams, param); } } } return; } if (SimpleFeatureCollection.class.isAssignableFrom(param.type) || FeatureCollection.class.isAssignableFrom(param.type)) { // vector layer parameters FeatureCollectionDataWidget featuresView = new FeatureCollectionDataWidget(map); featuresView.create(container, SWT.NONE, inputParams, param, uiParams); } else if (GridCoverage2D.class.isAssignableFrom(param.type)) { // raster layer parameters GridCoverageDataWidget gridCoverageView = new GridCoverageDataWidget(map); gridCoverageView.create(container, SWT.NONE, inputParams, param); } else if (Geometry.class.isAssignableFrom(param.type)) { // wkt geometry parameters GeometryWidget geometryView = new GeometryWidget(map); geometryView.create(container, SWT.NONE, inputParams, param); } else if (Filter.class.isAssignableFrom(param.type)) { // filter parameters FilterWidget filterView = new FilterWidget(map); filterView.create(container, SWT.NONE, inputParams, param); } else if (Expression.class.isAssignableFrom(param.type)) { // expression parameters ExpressionWidget expressionView = new ExpressionWidget(map); expressionView.create(container, SWT.NONE, inputParams, param, uiParams); } else if (CoordinateReferenceSystem.class.isAssignableFrom(param.type)) { // coordinate reference system parameters CrsWidget crsView = new CrsWidget(map); crsView.create(container, SWT.NONE, inputParams, param); } else if (BoundingBox.class.isAssignableFrom(param.type)) { // bounding box parameters BoundingBoxWidget boundingBoxView = new BoundingBoxWidget(map); boundingBoxView.create(container, SWT.NONE, inputParams, param); } else if (param.type.isEnum()) { // enumeration parameters EnumDataWidget enumView = new EnumDataWidget(); enumView.create(container, SWT.NONE, inputParams, param); } else if (Number.class.isAssignableFrom(param.type)) { // number parameters = Byte, Double, Float, Integer, Long, Short if (Double.class.isAssignableFrom(param.type) || Float.class.isAssignableFrom(param.type)) { NumberDataWidget numberView = new NumberDataWidget(map); numberView.create(container, SWT.NONE, inputParams, param); } else { IntegerDataWidget integerView = new IntegerDataWidget(map); integerView.create(container, SWT.NONE, inputParams, param); } } else if (Boolean.class.isAssignableFrom(param.type) || boolean.class.isAssignableFrom(param.type)) { // boolean parameters BooleanDataWidget booleanView = new BooleanDataWidget(); booleanView.create(container, SWT.NONE, inputParams, param); } else { Map<String, Object> metadata = param.metadata; if (metadata == null || metadata.size() == 0) { // other literal parameters LiteralDataWidget literalView = new LiteralDataWidget(map); literalView.create(container, SWT.NONE, inputParams, param); } else { if (metadata.containsKey(Params.FIELD)) { LiteralDataFieldWidget fieldView = new LiteralDataFieldWidget(map); fieldView.create(container, SWT.NONE, inputParams, param, uiParams); } else if (metadata.containsKey(Params.FIELDS)) { LiteralDataFieldsWidget fieldView = new LiteralDataFieldsWidget(map); fieldView.create(container, SWT.NONE, inputParams, param, uiParams); } else { // other literal parameters LiteralDataWidget literalView = new LiteralDataWidget(map); literalView.create(container, SWT.NONE, inputParams, param); } } } } private boolean validOutput() { for (Entry<String, Object> entrySet : outputParams.entrySet()) { File outputFile = new File(outputParams.get(entrySet.getKey()).toString()); if (!outputFile.exists()) { continue; } String msg = Messages.ProcessExecutionDialog_overwriteconfirm; if (MessageDialog.openConfirm(getParentShell(), getShell().getText(), msg)) { if (!MapUtils.confirmSpatialFile(outputFile)) { msg = Messages.ProcessExecutionDialog_deletefailed; MessageDialog.openInformation(getParentShell(), getShell().getText(), msg); return false; } } else { return false; } } return true; } @SuppressWarnings("nls") @Override protected void okPressed() { // check required parameters Map<String, Parameter<?>> paramInfo = factory.getParameterInfo(processName); for (Entry<String, Parameter<?>> entrySet : paramInfo.entrySet()) { String key = entrySet.getValue().key; if (entrySet.getValue().required && inputParams.get(key) == null) { StringBuffer sb = new StringBuffer(Messages.ProcessExecutionDialog_requiredparam); sb.append(System.getProperty("line.separator")).append(" - "); sb.append(entrySet.getValue().getTitle()); MessageDialog.openInformation(getParentShell(), windowTitle, sb.toString()); return; } } // check output files if (!validOutput()) { return; } ProcessExecutorOperation runnable = new ProcessExecutorOperation(map, factory, processName, inputParams, outputParams); try { new ProgressMonitorDialog(getParentShell()).run(true, true, runnable); } catch (InvocationTargetException e) { ToolboxPlugin.log(e.getMessage()); MessageDialog.openError(getParentShell(), Messages.General_Error, e.getMessage()); } catch (InterruptedException e) { ToolboxPlugin.log(e.getMessage()); MessageDialog.openInformation(getParentShell(), Messages.General_Cancelled, e.getMessage()); } if (outputTabRequired) { String outputText = runnable.getOutputText(); if (outputText.length() > 0) { outputTab.getParent().setSelection(outputTab); browser.setText(outputText); } } else { super.okPressed(); LayersView.getViewPart() .setCurrentMap((org.locationtech.udig.project.internal.Map) map); } } }