/**
* DataCleaner (community edition)
* Copyright (C) 2014 Neopost - Customer Information Management
*
* 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.widgets.properties;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.MutableColumn;
import org.apache.metamodel.util.CollectionUtils;
import org.datacleaner.actions.AddExpressionBasedColumnActionListener;
import org.datacleaner.actions.ReorderColumnsActionListener;
import org.datacleaner.api.InputColumn;
import org.datacleaner.beans.StringAnalyzer;
import org.datacleaner.beans.transform.ConcatenatorTransformer;
import org.datacleaner.configuration.DataCleanerConfiguration;
import org.datacleaner.configuration.DataCleanerConfigurationImpl;
import org.datacleaner.data.ELInputColumn;
import org.datacleaner.data.MutableInputColumn;
import org.datacleaner.descriptors.ConfiguredPropertyDescriptor;
import org.datacleaner.job.builder.AnalysisJobBuilder;
import org.datacleaner.job.builder.AnalyzerComponentBuilder;
import org.datacleaner.job.builder.TransformerComponentBuilder;
import org.datacleaner.widgets.DCCheckBox;
import junit.framework.TestCase;
public class MultipleInputColumnsPropertyWidgetTest extends TestCase {
public void testDefaultSelectAll() throws Exception {
final DataCleanerConfiguration configuration = new DataCleanerConfigurationImpl();
try (AnalysisJobBuilder ajb = new AnalysisJobBuilder(configuration)) {
ajb.addSourceColumn(new MutableColumn("foo", ColumnType.VARCHAR));
final MutableColumn barColumn = new MutableColumn("bar", ColumnType.VARCHAR);
ajb.addSourceColumn(barColumn);
ajb.addSourceColumn(new MutableColumn("baz", ColumnType.INTEGER));
final AnalyzerComponentBuilder<StringAnalyzer> beanJobBuilder = ajb.addAnalyzer(StringAnalyzer.class);
final ConfiguredPropertyDescriptor property =
beanJobBuilder.getDescriptor().getConfiguredPropertiesForInput().iterator().next();
final MultipleInputColumnsPropertyWidget widget =
new MultipleInputColumnsPropertyWidget(beanJobBuilder, property);
widget.onPanelAdd();
// initialize with null
widget.initialize(null);
widget.selectAll();
InputColumn<?>[] value = widget.getValue();
assertEquals("[MetaModelInputColumn[foo], MetaModelInputColumn[bar]]", Arrays.toString(value));
// add another available column
ajb.addSourceColumn(new MutableColumn("foobar", ColumnType.VARCHAR));
value = widget.getValue();
assertEquals("[MetaModelInputColumn[foo], MetaModelInputColumn[bar]]", Arrays.toString(value));
assertEquals("foo,bar,foobar", getAvailableCheckBoxValues(widget));
// remove a column
ajb.removeSourceColumn(barColumn);
value = widget.getValue();
assertEquals("[MetaModelInputColumn[foo]]", Arrays.toString(value));
assertEquals("foo,foobar", getAvailableCheckBoxValues(widget));
widget.onPanelRemove();
}
}
public void testAddAndRemoveExpressionColumn() throws Exception {
final DataCleanerConfiguration configuration = new DataCleanerConfigurationImpl();
try (AnalysisJobBuilder ajb = new AnalysisJobBuilder(configuration)) {
ajb.addSourceColumn(new MutableColumn("foo", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("bar", ColumnType.VARCHAR));
final AnalyzerComponentBuilder<StringAnalyzer> beanJobBuilder = ajb.addAnalyzer(StringAnalyzer.class);
final ConfiguredPropertyDescriptor property =
beanJobBuilder.getDescriptor().getConfiguredPropertiesForInput().iterator().next();
// initialize with a expression column
final MultipleInputColumnsPropertyWidget widget =
new MultipleInputColumnsPropertyWidget(beanJobBuilder, property);
InputColumn<?>[] value = new InputColumn[] { new ELInputColumn("Hello #{name}") };
widget.initialize(value);
value = widget.getValue();
assertEquals("[ELInputColumn[Hello #{name}]]", Arrays.toString(value));
assertEquals("\"Hello #{name}\",foo,bar", getAvailableCheckBoxValues(widget));
// select another column
widget.setValue(new InputColumn[] { ajb.getSourceColumnByName("bar") });
value = widget.getValue();
assertEquals("[MetaModelInputColumn[bar]]", Arrays.toString(value));
assertEquals("\"Hello #{name}\",foo,bar", getAvailableCheckBoxValues(widget));
// simulate clicking the EL button
AddExpressionBasedColumnActionListener.forMultipleColumns(widget)
.addExpressionBasedInputColumn("Hi #{nickname}");
value = widget.getValue();
assertEquals("[MetaModelInputColumn[bar], ELInputColumn[Hi #{nickname}]]", Arrays.toString(value));
assertEquals("\"Hello #{name}\",foo,bar,\"Hi #{nickname}\"", getAvailableCheckBoxValues(widget));
// add the same expression two times!
AddExpressionBasedColumnActionListener.forMultipleColumns(widget)
.addExpressionBasedInputColumn("Hi #{nickname}");
value = widget.getValue();
assertEquals("[MetaModelInputColumn[bar], ELInputColumn[Hi #{nickname}]]", Arrays.toString(value));
assertEquals("\"Hello #{name}\",foo,bar,\"Hi #{nickname}\"", getAvailableCheckBoxValues(widget));
}
}
public void testInitializeReordered() throws Exception {
final DataCleanerConfiguration configuration = new DataCleanerConfigurationImpl();
try (AnalysisJobBuilder ajb = new AnalysisJobBuilder(configuration)) {
ajb.addSourceColumn(new MutableColumn("foo", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("bar", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("baz", ColumnType.NVARCHAR));
final AnalyzerComponentBuilder<StringAnalyzer> beanJobBuilder = ajb.addAnalyzer(StringAnalyzer.class);
final ConfiguredPropertyDescriptor property =
beanJobBuilder.getDescriptor().getConfiguredPropertiesForInput().iterator().next();
// initialize with "baz" + "foo"
final MultipleInputColumnsPropertyWidget widget =
new MultipleInputColumnsPropertyWidget(beanJobBuilder, property);
final InputColumn<?>[] value =
new InputColumn[] { ajb.getSourceColumnByName("baz"), ajb.getSourceColumnByName("foo") };
widget.initialize(value);
assertEquals("baz,foo,bar", getAvailableCheckBoxValues(widget));
assertEquals("[MetaModelInputColumn[baz], MetaModelInputColumn[foo]]", Arrays.toString(widget.getValue()));
}
}
public void testShouldNotReorderColumnsWhenGettingAndSettingValue() throws Exception {
final DataCleanerConfiguration configuration = new DataCleanerConfigurationImpl();
try (AnalysisJobBuilder ajb = new AnalysisJobBuilder(configuration)) {
ajb.addSourceColumn(new MutableColumn("foo", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("bar", ColumnType.VARCHAR));
final TransformerComponentBuilder<ConcatenatorTransformer> transformer =
ajb.addTransformer(ConcatenatorTransformer.class);
transformer.addInputColumns(ajb.getSourceColumns());
final MutableInputColumn<?> transformedColumn = transformer.getOutputColumns().get(0);
transformedColumn.setName("baz");
final AnalyzerComponentBuilder<StringAnalyzer> analyzer = ajb.addAnalyzer(StringAnalyzer.class);
final ConfiguredPropertyDescriptor property = analyzer.getDescriptor().getConfiguredProperty("Columns");
// add columns in this sequence: foo, baz, bar
analyzer.addInputColumn(ajb.getSourceColumnByName("foo"), property);
analyzer.addInputColumn(transformedColumn, property);
analyzer.addInputColumn(ajb.getSourceColumnByName("bar"), property);
final InputColumn<?>[] propertyValue = (InputColumn<?>[]) analyzer.getConfiguredProperty(property);
assertEquals(3, propertyValue.length);
final MultipleInputColumnsPropertyWidget widget =
new MultipleInputColumnsPropertyWidget(analyzer, property);
widget.onOutputChanged(transformer, transformer.getOutputColumns());
widget.initialize(propertyValue);
assertEquals(
"[MetaModelInputColumn[foo], TransformedInputColumn[id=trans-0001-0002,name=baz], MetaModelInputColumn[bar]]",
Arrays.toString(widget.getValue()));
}
}
public void testReorderColumns() throws Exception {
final DataCleanerConfiguration configuration = new DataCleanerConfigurationImpl();
try (AnalysisJobBuilder ajb = new AnalysisJobBuilder(configuration)) {
ajb.addSourceColumn(new MutableColumn("foo", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("bar", ColumnType.VARCHAR));
ajb.addSourceColumn(new MutableColumn("baz", ColumnType.LONGVARCHAR));
final AnalyzerComponentBuilder<StringAnalyzer> beanJobBuilder = ajb.addAnalyzer(StringAnalyzer.class);
final ConfiguredPropertyDescriptor property =
beanJobBuilder.getDescriptor().getConfiguredPropertiesForInput().iterator().next();
// initialize with all 3 columns + an expression
final MultipleInputColumnsPropertyWidget widget =
new MultipleInputColumnsPropertyWidget(beanJobBuilder, property);
final InputColumn<?>[] value = CollectionUtils
.array(ajb.getSourceColumns().toArray(new InputColumn[0]), new ELInputColumn("Hello #{name}"));
widget.initialize(value);
assertEquals("foo,bar,baz,\"Hello #{name}\"", getAvailableCheckBoxValues(widget));
final ArrayList<InputColumn<?>> reorderedValue = new ArrayList<>(Arrays.asList(value));
reorderedValue.add(1, reorderedValue.remove(3));
new ReorderColumnsActionListener(widget).saveReorderedValue(reorderedValue);
assertEquals("foo,\"Hello #{name}\",bar,baz", getAvailableCheckBoxValues(widget));
assertEquals("[MetaModelInputColumn[foo], ELInputColumn[Hello #{name}], MetaModelInputColumn[bar], "
+ "MetaModelInputColumn[baz]]", Arrays.toString(widget.getValue()));
}
}
/**
* Helper method to determine which checkboxes are shown
*
* @param widget
* @return
*/
private String getAvailableCheckBoxValues(final MultipleInputColumnsPropertyWidget widget) {
final StringBuilder sb = new StringBuilder();
final Component[] components = widget.getWidget().getComponents();
for (final Component component : components) {
if (component instanceof DCCheckBox) {
@SuppressWarnings("unchecked") final DCCheckBox<InputColumn<?>> checkBox =
(DCCheckBox<InputColumn<?>>) component;
final String name = checkBox.getValue().getName();
if (sb.length() > 0) {
sb.append(',');
}
sb.append(name);
}
}
return sb.toString();
}
}