/* * Copyright (C) 2014 by Array Systems Computing Inc. http://www.array.ca * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.graphbuilder.gpf.ui; import com.bc.ceres.binding.ConversionException; import com.bc.ceres.binding.Converter; import com.bc.ceres.binding.ConverterRegistry; import com.bc.ceres.binding.Property; import com.bc.ceres.binding.PropertyContainer; import com.bc.ceres.binding.PropertyDescriptor; import com.bc.ceres.binding.PropertySet; import com.bc.ceres.binding.PropertySetDescriptor; import com.bc.ceres.binding.dom.DomConverter; import com.bc.ceres.binding.dom.DomElement; import com.bc.ceres.binding.dom.XppDomElement; import com.thoughtworks.xstream.io.xml.xppdom.XppDom; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.gpf.GPF; import org.esa.snap.core.gpf.OperatorSpi; import org.esa.snap.core.gpf.annotations.ParameterDescriptorFactory; import org.esa.snap.core.gpf.descriptor.OperatorDescriptor; import org.esa.snap.core.gpf.descriptor.PropertySetDescriptorFactory; import org.esa.snap.core.gpf.graph.GraphException; import org.esa.snap.ui.AppContext; import javax.swing.JComponent; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Map; import java.util.Set; /** * The abstract base class for all operator user interfaces intended to be extended by clients. * The following methods are intended to be implemented or overidden: * CreateOpTab() must be implemented in order to create the operator user interface component * User: lveci * Date: Feb 12, 2008 */ public abstract class BaseOperatorUI implements OperatorUI { protected PropertySet propertySet = null; protected Map<String, Object> paramMap = null; protected Product[] sourceProducts = null; protected String operatorName = ""; public abstract JComponent CreateOpTab(final String operatorName, final Map<String, Object> parameterMap, final AppContext appContext); public abstract void initParameters(); public abstract UIValidation validateParameters(); public abstract void updateParameters(); public String getOperatorName() { return operatorName; } protected void initializeOperatorUI(final String operatorName, final Map<String, Object> parameterMap) { this.operatorName = operatorName; this.paramMap = parameterMap; final OperatorSpi operatorSpi = GPF.getDefaultInstance().getOperatorSpiRegistry().getOperatorSpi(operatorName); if (operatorSpi == null) { throw new IllegalArgumentException("operator " + operatorName + " not found"); } final ParameterDescriptorFactory descriptorFactory = new ParameterDescriptorFactory(); final OperatorDescriptor operatorDescriptor = operatorSpi.getOperatorDescriptor(); final PropertySetDescriptor propertySetDescriptor; try { propertySetDescriptor = PropertySetDescriptorFactory.createForOperator(operatorDescriptor, descriptorFactory.getSourceProductMap()); } catch (ConversionException e) { throw new IllegalStateException("Not able to init OperatorParameterSupport.", e); } propertySet = PropertyContainer.createMapBacked(paramMap, propertySetDescriptor); if (paramMap.isEmpty()) { try { propertySet.setDefaultValues(); } catch (IllegalStateException e) { // todo - handle exception here e.printStackTrace(); } } } public void setSourceProducts(final Product[] products) { if (sourceProducts == null || !Arrays.equals(sourceProducts, products)) { sourceProducts = products; if (paramMap != null) { initParameters(); } } } public boolean hasSourceProducts() { return sourceProducts != null; } public void convertToDOM(final XppDomElement parentElement) throws GraphException { if (propertySet == null) { setParamsToConfiguration(parentElement.getXppDom()); return; } final Property[] properties = propertySet.getProperties(); for (Property p : properties) { final PropertyDescriptor descriptor = p.getDescriptor(); final DomConverter domConverter = descriptor.getDomConverter(); if (domConverter != null) { try { final DomElement childElement = parentElement.createChild(getElementName(p)); domConverter.convertValueToDom(p.getValue(), childElement); } catch (ConversionException e) { e.printStackTrace(); } } else { final String itemAlias = descriptor.getItemAlias(); if (descriptor.getType().isArray() && itemAlias != null && !itemAlias.isEmpty()) { final DomElement childElement = descriptor.getItemsInlined() ? parentElement : parentElement.createChild(getElementName(p)); final Object array = p.getValue(); final Converter itemConverter = getItemConverter(descriptor); if (array != null && itemConverter != null) { final int arrayLength = Array.getLength(array); for (int i = 0; i < arrayLength; i++) { final Object component = Array.get(array, i); final DomElement itemElement = childElement.createChild(itemAlias); final String text = itemConverter.format(component); if (text != null && !text.isEmpty()) { itemElement.setValue(text); } } } } else { final DomElement childElement = parentElement.createChild(getElementName(p)); final Object childValue = p.getValue(); final Converter converter = descriptor.getConverter(); if(converter == null) { throw new GraphException(operatorName+" BaseOperatorUI: no coverter found for parameter "+descriptor.getName()); } String text = converter.format(childValue); if (text != null && !text.isEmpty()) { childElement.setValue(text); } } } } } protected String[] getBandNames() { final ArrayList<String> bandNames = new ArrayList<>(5); if (sourceProducts != null) { for (Product prod : sourceProducts) { if (sourceProducts.length > 1) { for (String name : prod.getBandNames()) { bandNames.add(name + "::" + prod.getName()); } } else { bandNames.addAll(Arrays.asList(prod.getBandNames())); } } } return bandNames.toArray(new String[bandNames.size()]); } protected String[] getGeometries() { final ArrayList<String> geometryNames = new ArrayList<>(5); if (sourceProducts != null) { for (Product prod : sourceProducts) { if (sourceProducts.length > 1) { for (String name : prod.getMaskGroup().getNodeNames()) { geometryNames.add(name + "::" + prod.getName()); } } else { geometryNames.addAll(Arrays.asList(prod.getMaskGroup().getNodeNames())); } } } return geometryNames.toArray(new String[geometryNames.size()]); } private void setParamsToConfiguration(final XppDom config) { if (paramMap == null) return; final Set<String> keys = paramMap.keySet(); // The set of keys in the map. for (String key : keys) { final Object value = paramMap.get(key); // Get the value for that key. if (value == null) continue; XppDom xml = config.getChild(key); if (xml == null) { xml = new XppDom(key); config.addChild(xml); } xml.setValue(value.toString()); } } private static Converter getItemConverter(final PropertyDescriptor descriptor) { final Class<?> itemType = descriptor.getType().getComponentType(); Converter itemConverter = descriptor.getConverter(); if (itemConverter == null) { itemConverter = ConverterRegistry.getInstance().getConverter(itemType); } return itemConverter; } private static String getElementName(final Property p) { final String alias = p.getDescriptor().getAlias(); if (alias != null && !alias.isEmpty()) { return alias; } return p.getDescriptor().getName(); } }