/**
* 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.job.builder;
import static org.easymock.EasyMock.*;
import java.io.File;
import java.util.Collection;
import java.util.List;
import org.apache.metamodel.schema.MutableColumn;
import org.apache.metamodel.schema.MutableTable;
import org.datacleaner.api.OutputDataStream;
import org.datacleaner.configuration.DataCleanerConfigurationImpl;
import org.datacleaner.data.MetaModelInputColumn;
import org.datacleaner.test.MockAnalyzer;
import org.datacleaner.test.MockFilter;
import org.datacleaner.test.MockFilter.Category;
import org.datacleaner.test.MockOutputDataStreamAnalyzer;
import org.datacleaner.test.MockTransformer;
import org.datacleaner.test.mock.MockDatastore;
import org.easymock.EasyMock;
import junit.framework.TestCase;
public class AnalysisJobBuilderTest extends TestCase {
private MutableTable _table;
private MutableColumn _column;
private AnalysisJobBuilder _ajb;
@Override
protected void setUp() throws Exception {
_table = new MutableTable("table");
_column = new MutableColumn("foo").setTable(_table);
_table.addColumn(_column);
_ajb = new AnalysisJobBuilder(new DataCleanerConfigurationImpl());
_ajb.addSourceColumn(new MetaModelInputColumn(_column));
}
@Override
protected void tearDown() throws Exception {
_ajb.close();
}
public void testGetAvailableInputColumnsForComponentPreventsCyclicDependencies() throws Exception {
final TransformerComponentBuilder<MockTransformer> transformer1 = _ajb.addTransformer(MockTransformer.class);
transformer1.addInputColumn(_ajb.getSourceColumnByName("foo"));
transformer1.getOutputColumns().get(0).setName("out1");
assertEquals("[TransformedInputColumn[id=trans-0001-0002,name=out1]]",
transformer1.getOutputColumns().toString());
assertEquals("[MetaModelInputColumn[table.foo]]", _ajb.getAvailableInputColumns(transformer1).toString());
final TransformerComponentBuilder<MockTransformer> transformer2 = _ajb.addTransformer(MockTransformer.class);
transformer2.addInputColumn(transformer1.getOutputColumns().get(0));
transformer2.getOutputColumns().get(0).setName("out2");
assertEquals("[MetaModelInputColumn[table.foo]]", _ajb.getAvailableInputColumns(transformer1).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1]]",
_ajb.getAvailableInputColumns(transformer2).toString());
final TransformerComponentBuilder<MockTransformer> transformer3 = _ajb.addTransformer(MockTransformer.class);
assertEquals("[MetaModelInputColumn[table.foo]]", _ajb.getAvailableInputColumns(transformer1).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1]]",
_ajb.getAvailableInputColumns(transformer2).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1], "
+ "TransformedInputColumn[id=trans-0003-0004,name=out2]]",
_ajb.getAvailableInputColumns(transformer3).toString());
transformer3.addInputColumn(_ajb.getSourceColumns().get(0));
transformer3.getOutputColumns().get(0).setName("out3");
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0005-0006,name=out3]]",
_ajb.getAvailableInputColumns(transformer1).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1], "
+ "TransformedInputColumn[id=trans-0005-0006,name=out3]]",
_ajb.getAvailableInputColumns(transformer2).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1], "
+ "TransformedInputColumn[id=trans-0003-0004,name=out2]]",
_ajb.getAvailableInputColumns(transformer3).toString());
transformer2.clearInputColumns();
transformer2.addInputColumn(transformer3.getOutputColumns().get(0));
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0003-0004,name=out2], "
+ "TransformedInputColumn[id=trans-0005-0006,name=out3]]",
_ajb.getAvailableInputColumns(transformer1).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1], "
+ "TransformedInputColumn[id=trans-0005-0006,name=out3]]",
_ajb.getAvailableInputColumns(transformer2).toString());
assertEquals("[MetaModelInputColumn[table.foo], TransformedInputColumn[id=trans-0001-0002,name=out1]]",
_ajb.getAvailableInputColumns(transformer3).toString());
}
/**
* Builds a scenario with 2 transformers and a filter inbetween. When a
* filter outcome is set as the default requirement, that requirement should
* only be set on the succeeding (not preceeding) transformer.
*/
public void testSetDefaultRequirementNonCyclic() throws Exception {
final MockDatastore datastore = new MockDatastore();
_ajb.setDatastore(datastore);
_ajb.addSourceColumn(new MetaModelInputColumn(_column));
// add a transformer
final TransformerComponentBuilder<MockTransformer> tjb1 = _ajb.addTransformer(MockTransformer.class);
tjb1.addInputColumn(_ajb.getSourceColumns().get(0));
assertTrue(tjb1.isConfigured(true));
// add filter
final FilterComponentBuilder<MockFilter, Category> filter = _ajb.addFilter(MockFilter.class);
filter.addInputColumn(tjb1.getOutputColumns().get(0));
filter.getComponentInstance().setSomeEnum(Category.VALID);
filter.getComponentInstance().setSomeFile(new File("."));
assertTrue(filter.isConfigured(true));
// set default requirement
_ajb.setDefaultRequirement(filter, Category.VALID);
// add another transformer
final TransformerComponentBuilder<MockTransformer> tjb2 = _ajb.addTransformer(MockTransformer.class);
tjb2.addInputColumn(tjb1.getOutputColumns().get(0));
assertTrue(tjb2.isConfigured(true));
// assertions
assertEquals("Mock filter=VALID", tjb2.getComponentRequirement().toString());
assertEquals(null, filter.getComponentRequirement());
assertEquals(null, tjb1.getComponentRequirement());
final Collection<ComponentBuilder> componentBuilders = _ajb.getComponentBuilders();
assertEquals("[FilterComponentBuilder[filter=Mock filter,inputColumns="
+ "[TransformedInputColumn[id=trans-0001-0002,name=mock output]]], "
+ "TransformerComponentBuilder[transformer=Mock transformer,inputColumns="
+ "[MetaModelInputColumn[table.foo]]], "
+ "TransformerComponentBuilder[transformer=Mock transformer,inputColumns="
+ "[TransformedInputColumn[id=trans-0001-0002,name=mock output]]]]", componentBuilders.toString());
}
public void testGetAllJobBuilders() {
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer0 =
_ajb.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer0.setName("analyzer0");
analyzer0.addInputColumn(_ajb.getSourceColumns().get(0));
final List<OutputDataStream> analyzer0OutputDataStreams = analyzer0.getOutputDataStreams();
final AnalysisJobBuilder analyzer0DataStream0JobBuilder =
analyzer0.getOutputDataStreamJobBuilder(analyzer0OutputDataStreams.get(0));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer0Analyzer0 =
analyzer0DataStream0JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer0Analyzer0.setName("analyzer0Analyzer0");
analyzer0Analyzer0.addInputColumn(analyzer0DataStream0JobBuilder.getSourceColumns().get(0));
final List<OutputDataStream> analyzer0Analyzer0OutputDataStreams = analyzer0Analyzer0.getOutputDataStreams();
final AnalysisJobBuilder analyzer0Analyzer0DataStream0JobBuilder =
analyzer0Analyzer0.getOutputDataStreamJobBuilder(analyzer0Analyzer0OutputDataStreams.get(0));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer0Analyzer0Analyzer0 =
analyzer0Analyzer0DataStream0JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer0Analyzer0Analyzer0.setName("analyzer0Analyzer0Analyzer0");
analyzer0Analyzer0Analyzer0.addInputColumn(analyzer0Analyzer0DataStream0JobBuilder.getSourceColumns().get(0));
final AnalysisJobBuilder analyzer0DataStream1JobBuilder =
analyzer0.getOutputDataStreamJobBuilder(analyzer0Analyzer0OutputDataStreams.get(1));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer0Analyzer1 =
analyzer0DataStream1JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer0Analyzer1.setName("analyzer0Analyzer1");
analyzer0Analyzer1.addInputColumn(analyzer0DataStream1JobBuilder.getSourceColumns().get(0));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer1 =
_ajb.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer1.setName("analyzer1");
analyzer1.addInputColumn(_ajb.getSourceColumns().get(0));
final List<OutputDataStream> analyzer1OutputDataStreams = analyzer1.getOutputDataStreams();
final AnalysisJobBuilder analyzer1DataStream0JobBuilder =
analyzer1.getOutputDataStreamJobBuilder(analyzer1OutputDataStreams.get(0));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer1Analyzer0 =
analyzer1DataStream0JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer1Analyzer0.setName("analyzer1Analyzer0");
analyzer1Analyzer0.addInputColumn(analyzer1DataStream0JobBuilder.getSourceColumns().get(0));
final List<OutputDataStream> analyzer1Analyzer0OutputDataStreams = analyzer1Analyzer0.getOutputDataStreams();
final AnalysisJobBuilder analyzer1Analyzer0DataStream0JobBuilder =
analyzer1Analyzer0.getOutputDataStreamJobBuilder(analyzer1Analyzer0OutputDataStreams.get(0));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer1Analyzer0Analyzer0 =
analyzer1Analyzer0DataStream0JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer1Analyzer0Analyzer0.setName("analyzer1Analyzer0Analyzer0");
analyzer1Analyzer0Analyzer0.addInputColumn(analyzer0Analyzer0DataStream0JobBuilder.getSourceColumns().get(0));
final AnalysisJobBuilder analyzer1DataStream1JobBuilder =
analyzer1.getOutputDataStreamJobBuilder(analyzer1Analyzer0OutputDataStreams.get(1));
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer1Analyzer1 =
analyzer1DataStream1JobBuilder.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer1Analyzer1.setName("analyzer1Analyzer1");
analyzer1Analyzer1.addInputColumn(analyzer0DataStream1JobBuilder.getSourceColumns().get(0));
// Any random analyzer should work:
assertEquals(_ajb, analyzer1Analyzer0.getAnalysisJobBuilder().getRootJobBuilder());
assertEquals(_ajb, analyzer0Analyzer0Analyzer0.getAnalysisJobBuilder().getRootJobBuilder());
assertEquals(_ajb, analyzer0.getAnalysisJobBuilder().getRootJobBuilder());
assertEquals(_ajb, analyzer0Analyzer0.getAnalysisJobBuilder().getRootJobBuilder());
}
public void testChildOutputDataStreamListeners() {
// Set up expectations for the listeners
final AnalysisJobChangeListener mockedAnalysisJobChangeListener = mock(AnalysisJobChangeListener.class);
mockedAnalysisJobChangeListener.onActivation(anyObject(AnalysisJobBuilder.class));
expectLastCall().times(3);
mockedAnalysisJobChangeListener.onDeactivation(anyObject(AnalysisJobBuilder.class));
expectLastCall().times(3);
final AnalyzerChangeListener analyzerChangeListener = mock(AnalyzerChangeListener.class);
analyzerChangeListener.onAdd(anyObject(AnalyzerComponentBuilder.class));
expectLastCall().times(2);
analyzerChangeListener.onRemove(anyObject(AnalyzerComponentBuilder.class));
expectLastCall().times(2);
analyzerChangeListener.onConfigurationChanged(anyObject(AnalyzerComponentBuilder.class));
expectLastCall().atLeastOnce();
final TransformerChangeListener transformerChangeListener = mock(TransformerChangeListener.class);
transformerChangeListener.onAdd(anyObject(TransformerComponentBuilder.class));
transformerChangeListener.onRemove(anyObject(TransformerComponentBuilder.class));
transformerChangeListener.onOutputChanged(anyObject(TransformerComponentBuilder.class), EasyMock.anyObject());
expectLastCall().times(2); // Both configuration and removal will
// trigger this
transformerChangeListener.onConfigurationChanged(anyObject(TransformerComponentBuilder.class));
expectLastCall().times(1);
final FilterChangeListener filterChangeListener = mock(FilterChangeListener.class);
filterChangeListener.onAdd(anyObject(FilterComponentBuilder.class));
filterChangeListener.onRemove(anyObject(FilterComponentBuilder.class));
filterChangeListener.onConfigurationChanged(anyObject(FilterComponentBuilder.class));
replay(mockedAnalysisJobChangeListener, analyzerChangeListener, transformerChangeListener,
filterChangeListener);
final AnalysisJobChangeListener realAnalysisJobChangeListener = new AnalysisJobChangeListener() {
@Override
public void onActivation(final AnalysisJobBuilder builder) {
builder.addAnalysisJobChangeListener(this);
builder.addAnalysisJobChangeListener(mockedAnalysisJobChangeListener);
builder.addAnalyzerChangeListener(analyzerChangeListener);
builder.addTransformerChangeListener(transformerChangeListener);
builder.addFilterChangeListener(filterChangeListener);
}
@Override
public void onDeactivation(final AnalysisJobBuilder builder) {
builder.removeAnalysisJobChangeListener(this);
builder.removeAnalysisJobChangeListener(mockedAnalysisJobChangeListener);
builder.removeAnalyzerChangeListener(analyzerChangeListener);
builder.removeTransformerChangeListener(transformerChangeListener);
builder.removeFilterChangeListener(filterChangeListener);
}
};
realAnalysisJobChangeListener.onActivation(_ajb);
final AnalyzerComponentBuilder<MockOutputDataStreamAnalyzer> analyzer0 =
_ajb.addAnalyzer(MockOutputDataStreamAnalyzer.class);
analyzer0.setName("analyzer0");
analyzer0.addInputColumn(_ajb.getSourceColumns().get(0));
final List<OutputDataStream> analyzer0OutputDataStreams = analyzer0.getOutputDataStreams();
final AnalysisJobBuilder childAnalysisJobBuilder =
analyzer0.getOutputDataStreamJobBuilder(analyzer0OutputDataStreams.get(0));
final AnalyzerComponentBuilder<MockAnalyzer> childAnalyzer =
childAnalysisJobBuilder.addAnalyzer(MockAnalyzer.class);
childAnalyzer.setName("childAnalyzer");
childAnalyzer.addInputColumn(childAnalysisJobBuilder.getSourceColumns().get(0));
childAnalysisJobBuilder.removeAllAnalyzers();
final TransformerComponentBuilder<MockTransformer> childTransformer =
childAnalysisJobBuilder.addTransformer(MockTransformer.class);
childTransformer.setName("childTransformer");
childTransformer.addInputColumn(childAnalysisJobBuilder.getSourceColumns().get(0));
childAnalysisJobBuilder.removeAllTransformers();
final FilterComponentBuilder<MockFilter, Category> childFilter =
childAnalysisJobBuilder.addFilter(MockFilter.class);
childFilter.setName("childFilter");
childFilter.addInputColumn(childAnalysisJobBuilder.getSourceColumns().get(0));
childAnalysisJobBuilder.removeAllFilters();
_ajb.removeAllAnalyzers();
verify(mockedAnalysisJobChangeListener, analyzerChangeListener, transformerChangeListener,
filterChangeListener);
}
}