public void assignProperties(
     Object component, ComponentDescriptor<?> descriptor, ComponentConfiguration configuration) {
   final Set<ConfiguredPropertyDescriptor> configuredProperties =
       descriptor.getConfiguredProperties();
   for (final ConfiguredPropertyDescriptor property : configuredProperties) {
     Object configuredValue = getValue(property, configuration);
     if (configuredValue == null) {
       setValue(property, component, null);
     } else {
       if (property.isArray()) {
         setValue(property, component, configuredValue);
       } else {
         if (configuredValue.getClass().isArray()) {
           if (Array.getLength(configuredValue) == 1) {
             configuredValue = Array.get(configuredValue, 0);
           } else if (Array.getLength(configuredValue) > 1) {
             throw new IllegalStateException(
                 "Cannot assign an array-value ("
                     + configuredValue
                     + ") to a non-array property ("
                     + property
                     + ")");
           } else {
             configuredValue = null;
           }
         }
         setValue(property, component, configuredValue);
       }
     }
   }
 }
 protected Object getValue(
     ConfiguredPropertyDescriptor propertyDescriptor,
     ComponentConfiguration componentConfiguration) {
   final Object value = componentConfiguration.getProperty(propertyDescriptor);
   logger.debug("Property '{}' in configuration: {}", propertyDescriptor.getName(), value);
   return value;
 }
  @Inject
  protected PropertyWidgetFactoryImpl(ComponentBuilder componentBuilder, DCModule dcModule) {
    _componentBuilder = componentBuilder;
    _dcModule = dcModule;
    _propertyWidgetCollection = new PropertyWidgetCollection(componentBuilder);

    final Set<ConfiguredPropertyDescriptor> mappedProperties =
        componentBuilder.getDescriptor().getConfiguredPropertiesByAnnotation(MappedProperty.class);
    for (ConfiguredPropertyDescriptor mappedProperty : mappedProperties) {
      MappedProperty annotation = mappedProperty.getAnnotation(MappedProperty.class);
      String mappedToName = annotation.value();
      ConfiguredPropertyDescriptor mappedToProperty =
          componentBuilder.getDescriptor().getConfiguredProperty(mappedToName);

      PropertyWidgetMapping propertyWidgetMapping =
          buildMappedPropertyWidget(mappedProperty, mappedToProperty);

      _propertyWidgetCollection.putMappedPropertyWidget(mappedProperty, propertyWidgetMapping);
      _propertyWidgetCollection.putMappedPropertyWidget(mappedToProperty, propertyWidgetMapping);
    }
  }
 protected void setValue(ConfiguredPropertyDescriptor property, Object component, Object value) {
   property.setValue(component, value);
 }
  public InsertIntoTableJobBuilderPresenter(
      AnalyzerComponentBuilder<InsertIntoTableAnalyzer> analyzerJobBuilder,
      WindowContext windowContext,
      PropertyWidgetFactory propertyWidgetFactory,
      DataCleanerConfiguration configuration,
      DCModule dcModule) {
    super(analyzerJobBuilder, propertyWidgetFactory);
    _overriddenPropertyWidgets = new HashMap<ConfiguredPropertyDescriptor, PropertyWidget<?>>();

    final AnalyzerDescriptor<InsertIntoTableAnalyzer> descriptor =
        analyzerJobBuilder.getDescriptor();
    assert descriptor.getComponentClass() == InsertIntoTableAnalyzer.class;

    _datastoreProperty = descriptor.getConfiguredProperty("Datastore");
    _schemaNameProperty = descriptor.getConfiguredProperty("Schema name");
    _tableNameProperty = descriptor.getConfiguredProperty("Table name");
    _inputColumnsProperty = descriptor.getConfiguredProperty("Values");
    _columnNamesProperty = descriptor.getConfiguredProperty("Column names");
    _bufferSizeProperty = descriptor.getConfiguredProperty("Buffer size");
    _truncateTableProperty = descriptor.getConfiguredProperty("Truncate table");
    _errorHandlingProperty = descriptor.getConfiguredProperty("How to handle insertion errors?");
    _errorFileLocationProperty = descriptor.getConfiguredProperty("Error log file location");
    _additionalErrorLogValuesProperty =
        descriptor.getConfiguredProperty("Additional error log values");

    // the Datastore property
    assert _datastoreProperty != null;
    assert _datastoreProperty.getType() == Datastore.class;
    final SingleDatastorePropertyWidget datastorePropertyWidget =
        new SingleDatastorePropertyWidget(
            analyzerJobBuilder, _datastoreProperty, configuration.getDatastoreCatalog(), dcModule);
    datastorePropertyWidget.setOnlyUpdatableDatastores(true);
    _overriddenPropertyWidgets.put(_datastoreProperty, datastorePropertyWidget);

    // The schema name (String) property
    final SchemaNamePropertyWidget schemaNamePropertyWidget =
        new SchemaNamePropertyWidget(analyzerJobBuilder, _schemaNameProperty);
    _overriddenPropertyWidgets.put(_schemaNameProperty, schemaNamePropertyWidget);

    // The table name (String) property
    final SingleTableNamePropertyWidget tableNamePropertyWidget =
        new SingleTableNamePropertyWidget(analyzerJobBuilder, _tableNameProperty, windowContext);
    _overriddenPropertyWidgets.put(_tableNameProperty, tableNamePropertyWidget);

    // the InputColumn<?>[] property
    assert _inputColumnsProperty != null;
    assert _inputColumnsProperty.getType() == InputColumn[].class;
    final MultipleMappedColumnsPropertyWidget inputColumnsPropertyWidget =
        new MultipleMappedPrefixedColumnsPropertyWidget(
            analyzerJobBuilder, _inputColumnsProperty, _columnNamesProperty, " → ");
    _overriddenPropertyWidgets.put(_inputColumnsProperty, inputColumnsPropertyWidget);

    // the String[] property
    assert _columnNamesProperty != null;
    assert _columnNamesProperty.getType() == String[].class;
    _overriddenPropertyWidgets.put(
        _columnNamesProperty, inputColumnsPropertyWidget.getMappedColumnNamesPropertyWidget());

    // chain combo boxes
    datastorePropertyWidget.connectToSchemaNamePropertyWidget(schemaNamePropertyWidget);
    schemaNamePropertyWidget.connectToTableNamePropertyWidget(tableNamePropertyWidget);

    tableNamePropertyWidget.addComboListener(
        new Listener<Table>() {
          @Override
          public void onItemSelected(Table item) {
            // update the column combo boxes when the table is selected
            inputColumnsPropertyWidget.setTable(item);
          }
        });

    // initialize
    schemaNamePropertyWidget.setDatastore(datastorePropertyWidget.getValue());
    tableNamePropertyWidget.setSchema(
        datastorePropertyWidget.getValue(), schemaNamePropertyWidget.getSchema());
    inputColumnsPropertyWidget.setTable(tableNamePropertyWidget.getTable());
  }
  protected PropertyWidgetMapping buildMappedPropertyWidget(
      ConfiguredPropertyDescriptor mappedProperty, ConfiguredPropertyDescriptor mappedToProperty) {
    if (mappedProperty.isArray()
        && mappedToProperty.isArray()
        && mappedToProperty.isInputColumn()) {
      // mapped strings
      if (mappedProperty.getBaseType() == String.class) {
        final MultipleMappedStringsPropertyWidget propertyWidget =
            new MultipleMappedStringsPropertyWidget(
                getComponentBuilder(), mappedToProperty, mappedProperty);
        final PropertyWidgetMapping mapping = new PropertyWidgetMapping();
        mapping.putMapping(mappedProperty, propertyWidget.getMappedStringsPropertyWidget());
        mapping.putMapping(mappedToProperty, propertyWidget);
        return mapping;
      }

      // mapped enums
      if (mappedProperty.getBaseType().isEnum()
          || mappedProperty.getBaseType() == EnumerationValue.class) {
        final MultipleMappedEnumsPropertyWidget propertyWidget =
            new MultipleMappedEnumsPropertyWidget(
                getComponentBuilder(), mappedToProperty, mappedProperty);
        final PropertyWidgetMapping mapping = new PropertyWidgetMapping();
        mapping.putMapping(mappedProperty, propertyWidget.getMappedEnumsPropertyWidget());
        mapping.putMapping(mappedToProperty, propertyWidget);
        return mapping;
      }
    }

    // schema structure mapping
    if (mappedProperty.getBaseType() == String.class && !mappedToProperty.isArray()) {
      // save the "mappedToPropertyWidget" since it may be need to be
      // reused when there is a chain of dependencies between mapped
      // properties
      final PropertyWidget<?> mappedToPropertyWidget =
          _propertyWidgetCollection.getMappedPropertyWidget(mappedToProperty);

      // mapped schema name
      if (mappedProperty.getAnnotation(SchemaProperty.class) != null
          && (mappedToProperty.getBaseType() == Datastore.class
              || mappedToProperty.getBaseType() == UpdateableDatastore.class)) {
        final SchemaNamePropertyWidget schemaPropertyWidget =
            new SchemaNamePropertyWidget(getComponentBuilder(), mappedProperty);
        final SingleDatastorePropertyWidget datastorePropertyWidget;
        if (mappedToPropertyWidget == null) {
          final DatastoreCatalog datastoreCatalog =
              getComponentBuilder()
                  .getAnalysisJobBuilder()
                  .getConfiguration()
                  .getDatastoreCatalog();
          datastorePropertyWidget =
              new SingleDatastorePropertyWidget(
                  getComponentBuilder(), mappedToProperty, datastoreCatalog, _dcModule);
        } else {
          datastorePropertyWidget = (SingleDatastorePropertyWidget) mappedToPropertyWidget;
        }

        datastorePropertyWidget.addComboListener(
            new DCComboBox.Listener<Datastore>() {
              @Override
              public void onItemSelected(Datastore item) {
                schemaPropertyWidget.setDatastore(item);
              }
            });

        final PropertyWidgetMapping mapping = new PropertyWidgetMapping();
        mapping.putMapping(mappedProperty, schemaPropertyWidget);
        mapping.putMapping(mappedToProperty, datastorePropertyWidget);
        return mapping;
      }

      // mapped table name
      if (mappedProperty.getAnnotation(TableProperty.class) != null
          && mappedToProperty.getAnnotation(SchemaProperty.class) != null) {

        final SingleTableNamePropertyWidget tablePropertyWidget =
            new SingleTableNamePropertyWidget(
                getComponentBuilder(), mappedProperty, getWindowContext());
        final SchemaNamePropertyWidget schemaPropertyWidget;
        if (mappedToPropertyWidget == null) {
          schemaPropertyWidget =
              new SchemaNamePropertyWidget(getComponentBuilder(), mappedToProperty);
        } else {
          schemaPropertyWidget = (SchemaNamePropertyWidget) mappedToPropertyWidget;
        }

        schemaPropertyWidget.connectToTableNamePropertyWidget(tablePropertyWidget);

        final PropertyWidgetMapping mapping = new PropertyWidgetMapping();
        mapping.putMapping(mappedProperty, tablePropertyWidget);
        mapping.putMapping(mappedToProperty, schemaPropertyWidget);
        return mapping;
      }

      // mapped column name(s)
      if (mappedProperty.getAnnotation(ColumnProperty.class) != null
          && mappedToProperty.getAnnotation(TableProperty.class) != null) {

        final SingleTableNamePropertyWidget tablePropertyWidget;
        if (mappedToPropertyWidget == null) {
          tablePropertyWidget =
              new SingleTableNamePropertyWidget(
                  getComponentBuilder(), mappedToProperty, getWindowContext());
        } else {
          tablePropertyWidget = (SingleTableNamePropertyWidget) mappedToPropertyWidget;
        }

        if (mappedProperty.isArray()) {
          // multiple mapped column names

          // TODO: Not yet implemented. This case needs to take care
          // of the fact that usually this is then ALSO mapped to an
          // array of input columns.
        } else {
          // mapped column name

          final SingleColumnNamePropertyWidget columnPropertyWidget =
              new SingleColumnNamePropertyWidget(mappedProperty, getComponentBuilder());
          tablePropertyWidget.addComboListener(
              new DCComboBox.Listener<Table>() {
                @Override
                public void onItemSelected(Table item) {
                  columnPropertyWidget.setTable(item);
                }
              });

          final PropertyWidgetMapping mapping = new PropertyWidgetMapping();
          mapping.putMapping(mappedProperty, columnPropertyWidget);
          mapping.putMapping(mappedToProperty, tablePropertyWidget);
          return mapping;
        }
      }
    }

    return null;
  }
  /**
   * Creates (and registers) a widget that fits the specified configured property.
   *
   * @param propertyDescriptor
   * @return
   */
  @Override
  public PropertyWidget<?> create(ConfiguredPropertyDescriptor propertyDescriptor) {
    // first check if there is a mapping created for this property
    // descriptor
    PropertyWidget<?> propertyWidget =
        _propertyWidgetCollection.getMappedPropertyWidget(propertyDescriptor);
    if (propertyWidget != null) {
      return propertyWidget;
    }
    final HiddenProperty hiddenProperty = propertyDescriptor.getAnnotation(HiddenProperty.class);
    if (hiddenProperty != null && hiddenProperty.hiddenForLocalAccess()) {
      return null;
    }
    if (propertyDescriptor.getAnnotation(Deprecated.class) != null) {
      return null;
    }

    if (getComponentBuilder() instanceof AnalyzerComponentBuilder) {
      AnalyzerComponentBuilder<?> analyzer = (AnalyzerComponentBuilder<?>) getComponentBuilder();
      if (analyzer.isMultipleJobsSupported()) {
        if (analyzer.isMultipleJobsDeterminedBy(propertyDescriptor)) {
          final MultipleInputColumnsPropertyWidget result =
              new MultipleInputColumnsPropertyWidget(analyzer, propertyDescriptor);
          return result;
        }
      }
    }

    // check for fitting property widgets by type
    final Class<?> type = propertyDescriptor.getBaseType();

    final Class<? extends PropertyWidget<?>> widgetClass;
    if (propertyDescriptor.isArray()) {
      if (propertyDescriptor.isInputColumn()) {
        widgetClass = MultipleInputColumnsPropertyWidget.class;
      } else if (ReflectionUtils.isString(type)) {
        widgetClass = MultipleStringPropertyWidget.class;
      } else if (type == Dictionary.class) {
        widgetClass = MultipleDictionariesPropertyWidget.class;
      } else if (type == SynonymCatalog.class) {
        widgetClass = MultipleSynonymCatalogsPropertyWidget.class;
      } else if (type == StringPattern.class) {
        widgetClass = MultipleStringPatternPropertyWidget.class;
      } else if (type == EnumerationValue.class
          && propertyDescriptor instanceof EnumerationProvider) {
        widgetClass = MultipleRemoteEnumPropertyWidget.class;
      } else if (type.isEnum()) {
        widgetClass = MultipleEnumPropertyWidget.class;
      } else if (type == Class.class) {
        widgetClass = MultipleClassesPropertyWidget.class;
      } else if (type == char.class) {
        widgetClass = MultipleCharPropertyWidget.class;
      } else if (ReflectionUtils.isNumber(type)) {
        widgetClass = MultipleNumberPropertyWidget.class;
      } else {
        // not yet implemented
        widgetClass = DummyPropertyWidget.class;
      }
    } else {

      if (propertyDescriptor.isInputColumn()) {
        if (_componentBuilder
                .getDescriptor()
                .getConfiguredPropertiesByType(InputColumn.class, true)
                .size()
            == 1) {
          // if there is only a single input column property, it
          // will
          // be displayed using radiobuttons.
          widgetClass = SingleInputColumnRadioButtonPropertyWidget.class;
        } else {
          // if there are multiple input column properties, they
          // will
          // be displayed using combo boxes.
          widgetClass = SingleInputColumnComboBoxPropertyWidget.class;
        }
      } else if (ReflectionUtils.isCharacter(type)) {
        widgetClass = SingleCharacterPropertyWidget.class;
      } else if (ReflectionUtils.isString(type)) {
        widgetClass = SingleStringPropertyWidget.class;
      } else if (ReflectionUtils.isBoolean(type)) {
        widgetClass = SingleBooleanPropertyWidget.class;
      } else if (ReflectionUtils.isNumber(type)) {
        widgetClass = SingleNumberPropertyWidget.class;
      } else if (ReflectionUtils.isDate(type)) {
        widgetClass = SingleDatePropertyWidget.class;
      } else if (type == Dictionary.class) {
        widgetClass = SingleDictionaryPropertyWidget.class;
      } else if (type == SynonymCatalog.class) {
        widgetClass = SingleSynonymCatalogPropertyWidget.class;
      } else if (type == StringPattern.class) {
        widgetClass = SingleStringPatternPropertyWidget.class;
      } else if (type == EnumerationValue.class
          && propertyDescriptor instanceof EnumerationProvider) {
        widgetClass = SingleRemoteEnumPropertyWidget.class;
      } else if (type.isEnum()) {
        widgetClass = SingleEnumPropertyWidget.class;
      } else if (ReflectionUtils.is(type, Resource.class)) {
        widgetClass = SingleResourcePropertyWidget.class;
      } else if (type == File.class) {
        widgetClass = SingleFilePropertyWidget.class;
      } else if (type == Pattern.class) {
        widgetClass = SinglePatternPropertyWidget.class;
      } else if (ReflectionUtils.is(type, Datastore.class)) {
        widgetClass = SingleDatastorePropertyWidget.class;
      } else if (type == Class.class) {
        widgetClass = SingleClassPropertyWidget.class;
      } else if (type == Map.class) {
        final Class<?> genericType1 = propertyDescriptor.getTypeArgument(0);
        final Class<?> genericType2 = propertyDescriptor.getTypeArgument(1);
        if (genericType1 == String.class && genericType2 == String.class) {
          widgetClass = MapStringToStringPropertyWidget.class;
        } else {
          // not yet implemented
          widgetClass = DummyPropertyWidget.class;
        }
      } else {
        // not yet implemented
        widgetClass = DummyPropertyWidget.class;
      }
    }

    final Injector injector = getInjectorForPropertyWidgets(propertyDescriptor);
    final PropertyWidget<?> result = injector.getInstance(widgetClass);
    return result;
  }