/* * * * Copyright (C) 2015 CS SI * * * * 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.ui.tooladapter.model; import com.bc.ceres.binding.*; import com.bc.ceres.binding.converters.ArrayConverter; import com.bc.ceres.binding.converters.StringConverter; import com.bc.ceres.swing.binding.BindingContext; import com.bc.ceres.swing.binding.PropertyEditor; import com.bc.ceres.swing.binding.PropertyEditorRegistry; import org.apache.commons.lang.StringUtils; import org.esa.snap.core.gpf.annotations.ParameterDescriptorFactory; import org.esa.snap.core.gpf.descriptor.ParameterDescriptor; import org.esa.snap.core.gpf.descriptor.PropertyAttributeException; import org.esa.snap.core.gpf.descriptor.ToolAdapterOperatorDescriptor; import org.esa.snap.core.gpf.descriptor.ToolParameterDescriptor; import javax.swing.*; import java.awt.event.FocusEvent; import java.lang.reflect.Method; import java.util.HashMap; import java.util.logging.Logger; import java.util.regex.Pattern; /** * @author Ramona Manda */ public class PropertyMemberUIWrapperFactory { public static PropertyMemberUIWrapper buildEmptyPropertyWrapper(){ return new PropertyMemberUIWrapper(null, null, null, null, -1, null) { public String getErrorValueMessage(Object value) { return null; } @Override protected void setMemberValue(Object value) throws PropertyAttributeException { } @Override public String getMemberValue() {return null;} @Override protected JComponent buildUIComponent() { return new JLabel(); } @Override protected String getValueFromUIComponent() throws PropertyAttributeException { return null; } }; } public static PropertyMemberUIWrapper buildPropertyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, PropertyMemberUIWrapper.CallBackAfterEdit callback) { switch (attributeName) { case "name": return buildNamePropertyWrapper(attributeName, property, opDescriptor, context, 100, callback); case "dataType": return buildTypePropertyWrapper(attributeName, property, opDescriptor, context, 150, callback); case "defaultValue": return buildValuePropertyEditorWrapper(attributeName, property, opDescriptor, context, 250, callback); default: break; } /*if (attributeName.equals("name")) { return buildNamePropertyWrapper(attributeName, property, opDescriptor, context, 100, callback); } if (attributeName.equals("dataType")) { return buildTypePropertyWrapper(attributeName, property, opDescriptor, context, 150, callback); } if (attributeName.equals("defaultValue")) { return buildValuePropertyEditorWrapper(attributeName, property, opDescriptor, context, 250, callback); }*/ Method getter = null; try { getter = property.getClass().getSuperclass().getDeclaredMethod("is" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1)); } catch (NoSuchMethodException ignored) { } Object value = null; try { value = property.getAttribute(attributeName); } catch (Exception ignored) { } //TODO class/superclass! if (getter != null || (value != null && value.getClass().getSuperclass().equals(Boolean.class))) { return buildBooleanPropertyWrapper(attributeName, property, opDescriptor, context, 30, callback); } try { getter = property.getClass().getSuperclass().getDeclaredMethod("get" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1)); } catch (NoSuchMethodException ignored) { } if (getter != null && getter.getReturnType().equals(String.class)) { return buildStringPropertyWrapper(attributeName, property, opDescriptor, context, 100, callback); } if (attributeName.equals("valueRange") || attributeName.equals("pattern") || attributeName.equals("valueSet")) { return buildStringPropertyWrapper(attributeName, property, opDescriptor, context, 150, callback); } return buildEmptyWrapper(attributeName, property, opDescriptor, context, 100, callback); } private static Object parseAttributeValue(String attributeName, String value, ToolParameterDescriptor property) throws PropertyAttributeException { if (value == null || value.length() == 0) { return null; } Method getter = null; try { getter = property.getClass().getSuperclass().getDeclaredMethod("get" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1)); if (getter != null && getter.getReturnType().equals(String.class)) { return value; } if (getter != null && getter.getReturnType().equals(String[].class)) { Object[] items = ValueSet.parseValueSet(value, String.class).getItems(); String[] result = new String[items.length]; for (int i = 0; i < items.length; i++) { result[i] = items[i].toString(); } return result; } if (getter != null && getter.getReturnType().equals(ValueRange.class)) { return ValueRange.parseValueRange(value); } if (getter != null && getter.getReturnType().equals(Pattern.class)) { return Pattern.compile(value); } } catch (Exception ex) { throw new PropertyAttributeException("Error on parsing the value " + value + " in order to set the value for attribute " + attributeName); } return value; } private static PropertyMemberUIWrapper buildStringPropertyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { public String getErrorValueMessage(Object value) { return null; } @Override protected void setMemberValue(Object value) throws PropertyAttributeException { property.setAttribute(attributeName, value); } @Override public String getMemberValue() throws PropertyAttributeException { Object obj = property.getAttribute(attributeName); if (obj == null) { return ""; } if (obj instanceof String[]) { return StringUtils.join(((String[]) obj), ArrayConverter.SEPARATOR); } return obj.toString(); } @Override protected JComponent buildUIComponent() throws Exception { JTextField field = new JTextField(getMemberValue()); return field; } @Override protected Object getValueFromUIComponent() throws PropertyAttributeException { return PropertyMemberUIWrapperFactory.parseAttributeValue(attributeName, ((JTextField) UIComponent).getText(), property); } }; } private static PropertyMemberUIWrapper buildBooleanPropertyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { @Override protected void setMemberValue(Object value) throws PropertyAttributeException { property.setAttribute(attributeName, value); } @Override public Boolean getMemberValue() throws PropertyAttributeException { Object obj = property.getAttribute(attributeName); return obj != null && (boolean) obj; } @Override protected JComponent buildUIComponent() throws PropertyAttributeException { JCheckBox button = new JCheckBox(); button.setSelected(getMemberValue()); return button; } @Override protected Boolean getValueFromUIComponent() throws PropertyAttributeException { return ((JCheckBox) UIComponent).isSelected(); } }; } private static PropertyMemberUIWrapper buildNamePropertyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { public String getErrorValueMessage(Object value) { if (value == null || !(value instanceof String) || ((String) value).length() == 0) { return "Name of the property cannot be empty and must be a string!"; } if (property.getName().equals(value)) { return null; } //check if there is any other property with the same name, it should not! for (ParameterDescriptor prop : opDescriptor.getParameterDescriptors()) { if (prop != property && prop.getName().equals((value))) { return "The operator must not have more then one parameter with the same name!"; } } return null; } @Override protected void setMemberValue(Object value) throws PropertyAttributeException { property.setName(value != null ? value.toString() : "null"); } @Override public String getMemberValue() { return property.getName(); } @Override protected JComponent buildUIComponent() { return new JTextField(getMemberValue()); } @Override protected String getValueFromUIComponent() throws PropertyAttributeException { return ((JTextField) UIComponent).getText(); } }; } private static PropertyMemberUIWrapper buildTypePropertyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { public String getErrorValueMessage(Object value) { if (value == null) { return "Type of the property cannot be empty!"; } return null; } @Override protected void setMemberValue(Object value) throws PropertyAttributeException { property.setDataType(value != null ? (Class<?>) value : String.class); } @Override public Class<?> getMemberValue() { return property.getDataType(); } @Override protected JComponent buildUIComponent() { return new JTextField(getMemberValue().getCanonicalName()); } @Override public boolean propertyUIComponentsNeedsRevalidation() { return true; } @Override protected Class<?> getValueFromUIComponent() throws PropertyAttributeException { try { return Class.forName(((JTextField) UIComponent).getText()); } catch (ClassNotFoundException ex) { throw new PropertyAttributeException("Type of the property not found in the libraries"); } } }; } private static PropertyMemberUIWrapper buildValuePropertyEditorWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { public String getErrorValueMessage(Object value) { return null; } @Override public void setMemberValue(Object value) throws PropertyAttributeException { } public JComponent reloadUIComponent(Class<?> newParamType) throws Exception{ property.setDataType(newParamType); Property oldProp = context.getPropertySet().getProperty(property.getName()); Object dirAttr = null; if(oldProp != null) { PropertyDescriptor descriptor = ParameterDescriptorFactory.convert(property, new ParameterDescriptorFactory().getSourceProductMap()); dirAttr = descriptor.getAttribute("directory"); context.getPropertySet().removeProperty(oldProp); } PropertyDescriptor descriptor; try { descriptor = ParameterDescriptorFactory.convert(property, new ParameterDescriptorFactory().getSourceProductMap()); } catch (Exception ex) { property.setDefaultValue(null); descriptor = ParameterDescriptorFactory.convert(property, new ParameterDescriptorFactory().getSourceProductMap()); } descriptor.setDefaultConverter(); try { descriptor.setDefaultValue(property.getDefaultValue()); } catch (Exception ex) { Logger.getLogger(PropertyMemberUIWrapper.class.getName()).warning(ex.getMessage()); } try { descriptor.setValueSet(ValueSet.parseValueSet(property.getValueSet(), new StringConverter())); } catch (Exception ex) { Logger.getLogger(PropertyMemberUIWrapper.class.getName()).warning(ex.getMessage()); } DefaultPropertySetDescriptor propertySetDescriptor = new DefaultPropertySetDescriptor(); if (dirAttr != null) { descriptor.setAttribute("directory", dirAttr); } propertySetDescriptor.addPropertyDescriptor(descriptor); PropertyContainer container = PropertyContainer.createMapBacked(new HashMap<>(), propertySetDescriptor); context.getPropertySet().addProperties(container.getProperties()); return super.reloadUIComponent(newParamType); } @Override public Object getMemberValue() { return property.getDefaultValue(); } @Override protected JComponent buildUIComponent() { PropertyDescriptor propertydescriptor = context.getPropertySet().getDescriptor(property.getName()); PropertyEditor propertyEditor = PropertyEditorRegistry.getInstance().findPropertyEditor( propertydescriptor); return propertyEditor.createEditorComponent(propertydescriptor, context); } @Override protected Object getValueFromUIComponent() throws PropertyAttributeException { return null; } @Override public void focusLost(FocusEvent e){} }; } public static PropertyMemberUIWrapper buildEmptyWrapper(String attributeName, ToolParameterDescriptor property, ToolAdapterOperatorDescriptor opDescriptor, BindingContext context, int width, PropertyMemberUIWrapper.CallBackAfterEdit callback) { return new PropertyMemberUIWrapper(attributeName, property, opDescriptor, context, width, callback) { @Override public String getErrorValueMessage(Object value) { return null; } @Override protected void setMemberValue(Object value) throws PropertyAttributeException { } @Override public Object getMemberValue() { return null; } @Override protected JComponent buildUIComponent() { return new JLabel(""); } @Override protected Object getValueFromUIComponent() { return null; } }; } }