![JAR search and dependency download from the Maven repository](/logo.png)
org.datacleaner.panels.fuse.ColumnListMultipleCoalesceUnitPropertyWidget Maven / Gradle / Ivy
/**
* DataCleaner (community edition)
* Copyright (C) 2014 Free Software Foundation, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.datacleaner.panels.fuse;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.border.EmptyBorder;
import org.apache.commons.lang.ArrayUtils;
import org.apache.metamodel.util.EqualsBuilder;
import org.datacleaner.api.InputColumn;
import org.datacleaner.components.fuse.CoalesceUnit;
import org.datacleaner.components.fuse.CoalesceUnitMissingColumnException;
import org.datacleaner.data.MutableInputColumn;
import org.datacleaner.descriptors.ConfiguredPropertyDescriptor;
import org.datacleaner.job.builder.ComponentBuilder;
import org.datacleaner.job.builder.SourceColumnChangeListener;
import org.datacleaner.job.builder.TransformerChangeListener;
import org.datacleaner.job.builder.TransformerComponentBuilder;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.IconUtils;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.widgets.properties.AbstractPropertyWidget;
import org.datacleaner.widgets.properties.MinimalPropertyWidget;
import org.datacleaner.widgets.properties.PropertyWidget;
import org.jdesktop.swingx.VerticalLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link PropertyWidget} for two properties at one time: An array of
* {@link InputColumn}s and an array of {@link CoalesceUnit}s.
*
* This widget displays a list of {@link CoalesceUnit}s with {@link InputColumn}
* s that the user can add an remove from.
*/
public class ColumnListMultipleCoalesceUnitPropertyWidget extends AbstractPropertyWidget[]>
implements SourceColumnChangeListener, TransformerChangeListener, MutableInputColumn.Listener {
private static final Logger logger = LoggerFactory.getLogger(ColumnListMultipleCoalesceUnitPropertyWidget.class);
private final ConfiguredPropertyDescriptor _unitProperty;
private final MinimalPropertyWidget _unitPropertyWidget;
private final DCPanel _unitContainerPanel;
private final Set> _pickedInputColumns;
public ColumnListMultipleCoalesceUnitPropertyWidget(final ComponentBuilder componentBuilder,
final ConfiguredPropertyDescriptor inputProperty, final ConfiguredPropertyDescriptor unitProperty) {
super(componentBuilder, inputProperty);
_unitProperty = unitProperty;
_pickedInputColumns = new HashSet<>();
_unitContainerPanel = new DCPanel();
_unitContainerPanel.setLayout(new VerticalLayout(2));
getAnalysisJobBuilder().addSourceColumnChangeListener(this);
getAnalysisJobBuilder().addTransformerChangeListener(this);
_unitPropertyWidget = createUnitPropertyWidget();
final JButton addButton = WidgetFactory.createSmallButton(IconUtils.ACTION_ADD_DARK);
addButton.addActionListener(e -> addCoalesceUnit());
final JButton removeButton = WidgetFactory.createSmallButton(IconUtils.ACTION_REMOVE_DARK);
removeButton.addActionListener(e -> removeCoalesceUnit());
final DCPanel buttonPanel = new DCPanel();
buttonPanel.setBorder(new EmptyBorder(0, 4, 0, 0));
buttonPanel.setLayout(new VerticalLayout(2));
buttonPanel.add(addButton);
buttonPanel.add(removeButton);
final DCPanel outerPanel = new DCPanel();
outerPanel.setLayout(new BorderLayout());
outerPanel.add(_unitContainerPanel, BorderLayout.CENTER);
outerPanel.add(buttonPanel, BorderLayout.EAST);
add(outerPanel);
final CoalesceUnit[] currentValue = (CoalesceUnit[]) getComponentBuilder().getConfiguredProperty(_unitProperty);
if (currentValue == null) {
addCoalesceUnit();
} else {
batchUpdateWidget(() -> {
for (final CoalesceUnit unit : currentValue) {
addCoalesceUnit(unit);
}
});
}
}
@Override
public void onPanelRemove() {
super.onPanelRemove();
getAnalysisJobBuilder().removeSourceColumnChangeListener(this);
getAnalysisJobBuilder().removeTransformerChangeListener(this);
}
public void removeCoalesceUnit() {
final int componentCount = _unitContainerPanel.getComponentCount();
if (componentCount > 1) {
final int index = componentCount - 1;
_unitContainerPanel.remove(index);
_unitContainerPanel.updateUI();
fireBothValuesChanged();
}
updateUI();
}
private void removeCoalesceUnitPanel(final CoalesceUnitPanel coalesceUnitPanel) {
final int componentCount = _unitContainerPanel.getComponentCount();
if (componentCount > 1) {
_unitContainerPanel.remove(coalesceUnitPanel);
_unitContainerPanel.updateUI();
fireBothValuesChanged();
}
updateUI();
}
public void addCoalesceUnit(final CoalesceUnit unit) {
final CoalesceUnitPanel panel = new CoalesceUnitPanel(this, unit);
_unitContainerPanel.add(panel);
updateUI();
}
public void addCoalesceUnit() {
final CoalesceUnitPanel panel = new CoalesceUnitPanel(this);
_unitContainerPanel.add(panel);
fireBothValuesChanged();
updateUI();
}
private MinimalPropertyWidget createUnitPropertyWidget() {
return new MinimalPropertyWidget(getComponentBuilder(), _unitProperty) {
@Override
public JComponent getWidget() {
// do not return a visual widget
return null;
}
@Override
public CoalesceUnit[] getValue() {
final CoalesceUnit[] units = getCoalesceUnits();
if (units.length == 0) {
logger.debug("Returning Units.value = null");
return null;
}
if (logger.isDebugEnabled()) {
logger.debug("Returning Units.value = {}", Arrays.toString(units));
}
return units;
}
@Override
protected void setValue(final CoalesceUnit[] value) {
if (value == null) {
return;
}
if (EqualsBuilder.equals(value, getValue())) {
return;
}
setCoalesceUnits(value);
}
@Override
public boolean isSet() {
return ColumnListMultipleCoalesceUnitPropertyWidget.this.isSet();
}
};
}
@Override
public boolean isSet() {
final List panels = getCoalesceUnitPanels();
if (panels.isEmpty()) {
return false;
}
for (final CoalesceUnitPanel panel : panels) {
if (!panel.isSet()) {
return false;
}
}
return true;
}
private List getCoalesceUnitPanels() {
final List result = new ArrayList<>();
final Component[] components = _unitContainerPanel.getComponents();
for (final Component component : components) {
if (component instanceof CoalesceUnitPanel) {
result.add((CoalesceUnitPanel) component);
}
}
return result;
}
public CoalesceUnit[] getCoalesceUnits() {
final List panels = getCoalesceUnitPanels();
final List result = new ArrayList<>();
for (final CoalesceUnitPanel panel : panels) {
if (panel.isSet()) {
final CoalesceUnit unit = panel.getCoalesceUnit();
result.add(unit);
}
}
return result.toArray(new CoalesceUnit[result.size()]);
}
public void setCoalesceUnits(final CoalesceUnit[] units) {
batchUpdateWidget(() -> {
_unitContainerPanel.removeAll();
for (final CoalesceUnit unit : units) {
addCoalesceUnit(unit);
}
});
}
@Override
public InputColumn>[] getValue() {
final List> availableInputColumns =
getAnalysisJobBuilder().getAvailableInputColumns(Object.class);
final InputColumn>[] allInputColumns =
availableInputColumns.toArray(new InputColumn[availableInputColumns.size()]);
final List> resultList = new ArrayList<>();
final CoalesceUnit[] units = getCoalesceUnits();
if (units.length == 0) {
logger.debug("Returning Input.value = null");
return null;
}
for (final CoalesceUnit unit : units) {
final InputColumn>[] updatedInputColumns = unit.getUpdatedInputColumns(allInputColumns, true);
Collections.addAll(resultList, updatedInputColumns);
}
logger.debug("Returning Input.value = {}", resultList);
return resultList.toArray(new InputColumn[resultList.size()]);
}
@Override
protected void setValue(final InputColumn>[] value) {
// we ignore this setValue call since the setValue call of the
// unitPropertyWidget will also contain the input column references.
}
public PropertyWidget> getUnitPropertyWidget() {
return _unitPropertyWidget;
}
/**
* Called when an input column is picked (selected) by a child
* CoalesceUnitPanel
*
* @param item
*/
public void onInputColumnPicked(final InputColumn> item) {
_pickedInputColumns.add(item);
updateAvailableInputColumns();
fireBothValuesChanged();
}
/**
* Called when an input column is released (de-selected) by a child
* CoalesceUnitPanel
*
* @param item
*/
public void onInputColumnReleased(final InputColumn> item) {
_pickedInputColumns.remove(item);
updateAvailableInputColumns();
fireBothValuesChanged();
}
private void updateAvailableInputColumns() {
final List> availableInputColumns = getAvailableInputColumns();
final List panels = getCoalesceUnitPanels();
for (final CoalesceUnitPanel panel : panels) {
panel.setAvailableInputColumns(availableInputColumns);
}
}
public List> getAvailableInputColumns() {
final List> availableInputColumns =
getAnalysisJobBuilder().getAvailableInputColumns(Object.class);
if (getComponentBuilder() instanceof TransformerComponentBuilder) {
// remove all the columns that are generated by the transformer
// itself!
final TransformerComponentBuilder> tjb = (TransformerComponentBuilder>) getComponentBuilder();
final List> outputColumns = tjb.getOutputColumns();
availableInputColumns.removeAll(outputColumns);
}
availableInputColumns.removeAll(_pickedInputColumns);
return availableInputColumns;
}
@Override
public void onNameChanged(final MutableInputColumn> inputColumn, final String oldName, final String newName) {
updateAvailableInputColumns();
}
@Override
public void onVisibilityChanged(final MutableInputColumn> inputColumn, final boolean hidden) {
}
@Override
public void onAdd(final TransformerComponentBuilder> transformerJobBuilder) {
updateAvailableInputColumns();
}
@Override
public void onRemove(final TransformerComponentBuilder> transformerJobBuilder) {
updateAvailableInputColumns();
}
@Override
public void onConfigurationChanged(final TransformerComponentBuilder> transformerJobBuilder) {
}
@Override
public void onRequirementChanged(final TransformerComponentBuilder> transformerJobBuilder) {
}
@Override
public void onOutputChanged(final TransformerComponentBuilder> transformerJobBuilder,
final List> outputColumns) {
for (final MutableInputColumn> outputColumn : outputColumns) {
outputColumn.addListener(this);
}
updateAvailableInputColumns();
}
@Override
public void onValueTouched(final InputColumn>[] value) {
try {
super.onValueTouched(value);
} catch (final CoalesceUnitMissingColumnException e) {
logger.warn("Missing input column for coalesce unit", e);
final CoalesceUnit failingCoalesceUnit = e.getCoalesceUnit();
final CoalesceUnit[] newCoalesceUnits =
(CoalesceUnit[]) ArrayUtils.removeElement(_unitPropertyWidget.getValue(), failingCoalesceUnit);
for (final InputColumn> inputColumn : failingCoalesceUnit.getInputColumns()) {
_pickedInputColumns.remove(inputColumn);
}
getCoalesceUnitPanels().stream()
.filter(coalesceUnitPanel -> coalesceUnitPanel.getCoalesceUnit().equals(failingCoalesceUnit))
.forEach(this::removeCoalesceUnitPanel);
_unitPropertyWidget.onValueTouched(newCoalesceUnits);
updateAvailableInputColumns();
fireBothValuesChanged();
updateUI();
}
}
@Override
public void onAdd(final InputColumn> sourceColumn) {
updateAvailableInputColumns();
}
@Override
public void onRemove(final InputColumn> sourceColumn) {
updateAvailableInputColumns();
}
private void fireBothValuesChanged() {
if (!isUpdating() && !isBatchUpdating()) {
final Map properties = new HashMap<>();
properties.put(getPropertyDescriptor(), getValue());
properties.put(_unitProperty, _unitPropertyWidget.getValue());
fireValuesChanged(properties);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy