Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* 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.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import org.apache.metamodel.schema.Table;
import org.datacleaner.api.InputColumn;
import org.datacleaner.api.OutputDataStream;
import org.datacleaner.components.fuse.CoalesceUnit;
import org.datacleaner.data.MutableInputColumn;
import org.datacleaner.descriptors.ConfiguredPropertyDescriptor;
import org.datacleaner.job.builder.AnalysisJobBuilder;
import org.datacleaner.job.builder.ComponentBuilder;
import org.datacleaner.job.builder.TransformerChangeListener;
import org.datacleaner.job.builder.TransformerComponentBuilder;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.SourceColumnFinder;
import org.datacleaner.widgets.properties.AbstractPropertyWidget;
import org.datacleaner.widgets.properties.MinimalPropertyWidget;
import org.datacleaner.widgets.properties.PropertyWidget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* A {@link PropertyWidget} for representing both a property with an array of
* {@link CoalesceUnit}s and another property with an array of
* {@link InputColumn}s.
*
* This widget presents the incoming streams as columns and available
* {@link InputColumn}s from each stream as rows in a matrix where the user gets
* the design a new {@link OutputDataStream}.
*/
public class StreamColumnMatrixMultipleCoalesceUnitPropertyWidget extends AbstractPropertyWidget[]>
implements TransformerChangeListener, MutableInputColumn.Listener {
private static final Logger logger =
LoggerFactory.getLogger(StreamColumnMatrixMultipleCoalesceUnitPropertyWidget.class);
private final ConfiguredPropertyDescriptor _unitProperty;
private final MinimalPropertyWidget _unitPropertyWidget;
private final DCPanel _containerPanel;
private final List _tablePanels;
public StreamColumnMatrixMultipleCoalesceUnitPropertyWidget(final ComponentBuilder componentBuilder,
final ConfiguredPropertyDescriptor inputProperty, final ConfiguredPropertyDescriptor unitProperty) {
super(componentBuilder, inputProperty);
_unitProperty = unitProperty;
_tablePanels = new ArrayList<>();
getAnalysisJobBuilder().addTransformerChangeListener(this);
_containerPanel = new DCPanel();
_containerPanel.setLayout(new BoxLayout(_containerPanel, BoxLayout.X_AXIS));
_unitPropertyWidget = createUnitPropertyWidget();
// only facilitate horizontal scroll
final JScrollPane scroll = new JScrollPane(_containerPanel);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
add(scroll);
final CoalesceUnit[] coalesceUnits =
(CoalesceUnit[]) getComponentBuilder().getConfiguredProperty(_unitProperty);
refresh(coalesceUnits);
if (coalesceUnits != null) {
// Call fireValueChanged() to provoke the check for non-used
// streams. This cleans up the InputColumn[] property of streams
// that are not relevant at all. Another way to think of it is that
// irrelevant lines on the graph behind will be removed.
fireValueChanged();
}
}
private void refresh(final CoalesceUnit[] units) {
_tablePanels.clear();
_containerPanel.removeAll();
final AnalysisJobBuilder ajb = getAnalysisJobBuilder();
final InputColumn>[] inputColumns = ajb.getSourceColumns().toArray(new InputColumn[0]);
// TODO: We need a SourceColumnFinder that is aware of also nested jobs
final SourceColumnFinder sourceColumnFinder = new SourceColumnFinder();
sourceColumnFinder.addSources(ajb);
// build registries of available columns and coalesced columns
final Multimap
> allTablesAndColumns = ArrayListMultimap.create();
final Multimap
> coalescedTablesAndColumns = ArrayListMultimap.create();
for (final InputColumn> inputColumn : inputColumns) {
final Table table = sourceColumnFinder.findOriginatingTable(inputColumn);
allTablesAndColumns.put(table, inputColumn);
}
if (units != null) {
final List survivingCoalesceUnits = new ArrayList<>(units.length);
for (CoalesceUnit unit : units) {
// Not necessarily initialized yet, so no _initializedUnits available
final InputColumn>[] updatedInputColumns = unit.getUpdatedInputColumns(inputColumns, false);
if (updatedInputColumns.length > 0) {
unit = unit.getUpdatedCoalesceUnit(updatedInputColumns);
survivingCoalesceUnits.add(unit);
for (final InputColumn> inputColumn : updatedInputColumns) {
final Table originatingTable = sourceColumnFinder.findOriginatingTable(inputColumn);
coalescedTablesAndColumns.put(originatingTable, inputColumn);
}
}
}
if (!Arrays
.equals(units, survivingCoalesceUnits.toArray(new CoalesceUnit[survivingCoalesceUnits.size()]))) {
final Map properties = new HashMap<>();
properties.put(getPropertyDescriptor(), getValue());
properties.put(_unitProperty,
survivingCoalesceUnits.toArray(new CoalesceUnit[survivingCoalesceUnits.size()]));
fireValuesChanged(properties);
}
}
for (final Table table : allTablesAndColumns.keySet()) {
final StreamColumnListPanel tablePanel = new StreamColumnListPanel(ajb, table, panel -> {
fireValueChanged();
_unitPropertyWidget.fireValueChanged();
});
final Collection> selectedColumns = coalescedTablesAndColumns.get(table);
for (final InputColumn> inputColumn : selectedColumns) {
tablePanel.addInputColumn(inputColumn, true);
}
final Collection> columns = new ArrayList<>(allTablesAndColumns.get(table));
columns.removeAll(selectedColumns);
for (final InputColumn> inputColumn : columns) {
tablePanel.addInputColumn(inputColumn, false);
}
tablePanel.refresh();
_tablePanels.add(tablePanel);
_containerPanel.add(tablePanel);
}
}
@Override
public void onPanelRemove() {
super.onPanelRemove();
getAnalysisJobBuilder().removeTransformerChangeListener(this);
}
public PropertyWidget> getUnitPropertyWidget() {
return _unitPropertyWidget;
}
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) {
}
@Override
public boolean isSet() {
return StreamColumnMatrixMultipleCoalesceUnitPropertyWidget.this.isSet();
}
};
}
protected CoalesceUnit[] getCoalesceUnits() {
int max = 0;
final List>> allCoalescedInputColumns = new ArrayList<>();
for (final StreamColumnListPanel tablePanel : _tablePanels) {
final List> coalescedInputColumns = tablePanel.getCoalescedInputColumns();
allCoalescedInputColumns.add(coalescedInputColumns);
max = Math.max(max, coalescedInputColumns.size());
}
final CoalesceUnit[] result = new CoalesceUnit[max];
for (int i = 0; i < result.length; i++) {
final List> coalesceUnitInputColumns = new ArrayList<>();
for (final List> coalescedInputColumnsForTable : allCoalescedInputColumns) {
if (coalescedInputColumnsForTable.size() - 1 >= i) {
coalesceUnitInputColumns.add(coalescedInputColumnsForTable.get(i));
}
}
final CoalesceUnit unit = new CoalesceUnit(coalesceUnitInputColumns);
result[i] = unit;
}
return result;
}
@Override
public InputColumn>[] getValue() {
final List> result = new ArrayList<>();
for (final StreamColumnListPanel tablePanel : _tablePanels) {
if (tablePanel.hasSelectedInputColumns()) {
result.addAll(tablePanel.getAllInputColumns());
}
}
return result.toArray(new InputColumn>[result.size()]);
}
@Override
protected void setValue(final InputColumn>[] value) {
}
@Override
public void onNameChanged(final MutableInputColumn> inputColumn, final String oldName, final String newName) {
}
@Override
public void onVisibilityChanged(final MutableInputColumn> inputColumn, final boolean hidden) {
}
@Override
public void onOutputChanged(final TransformerComponentBuilder> transformerJobBuilder,
final List> outputColumns) {
if (transformerJobBuilder != getComponentBuilder()) {
refresh(getCoalesceUnits());
}
}
@Override
public void onAdd(final TransformerComponentBuilder> builder) {
}
@Override
public void onConfigurationChanged(final TransformerComponentBuilder> builder) {
}
@Override
public void onRequirementChanged(final TransformerComponentBuilder> builder) {
}
@Override
public void onRemove(final TransformerComponentBuilder> componentBuilder) {
}
}