Package org.eobjects.datacleaner.actions

Source Code of org.eobjects.datacleaner.actions.PreviewTransformedDataActionListener

/**
* eobjects.org DataCleaner
* Copyright (C) 2010 eobjects.org
*
* 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.eobjects.datacleaner.actions;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import org.eobjects.analyzer.connection.DataContextProvider;
import org.eobjects.analyzer.connection.DatastoreCatalog;
import org.eobjects.analyzer.data.InputColumn;
import org.eobjects.analyzer.data.InputRow;
import org.eobjects.analyzer.data.MetaModelInputRow;
import org.eobjects.analyzer.data.MutableInputColumn;
import org.eobjects.analyzer.data.TransformedInputRow;
import org.eobjects.analyzer.descriptors.ConfiguredPropertyDescriptor;
import org.eobjects.analyzer.descriptors.TransformerBeanDescriptor;
import org.eobjects.analyzer.job.builder.AnalysisJobBuilder;
import org.eobjects.analyzer.job.builder.TransformerJobBuilder;
import org.eobjects.analyzer.lifecycle.LifeCycleHelper;
import org.eobjects.analyzer.reference.ReferenceData;
import org.eobjects.analyzer.reference.ReferenceDataCatalog;
import org.eobjects.datacleaner.bootstrap.WindowContext;
import org.eobjects.datacleaner.panels.TransformerJobBuilderPresenter;
import org.eobjects.datacleaner.user.DCConfiguration;
import org.eobjects.datacleaner.windows.DataSetWindow;
import org.eobjects.metamodel.DataContext;
import org.eobjects.metamodel.MetaModelHelper;
import org.eobjects.metamodel.data.DataSet;
import org.eobjects.metamodel.data.Row;
import org.eobjects.metamodel.query.Query;
import org.eobjects.metamodel.schema.Column;
import org.eobjects.metamodel.schema.Table;

/**
* ActionListener responsible for previewing transformed data in a
* {@link DataSetWindow}.
*
* @author Kasper Sørensen
*/
public final class PreviewTransformedDataActionListener implements ActionListener, Callable<TableModel> {

  public static final int DEFAULT_PREVIEW_ROWS = 400;

  private final TransformerJobBuilderPresenter _transformerJobBuilderPresenter;
  private final AnalysisJobBuilder _analysisJobBuilder;
  private final TransformerJobBuilder<?> _transformerJobBuilder;
  private final LifeCycleHelper _lifeCycleHelper;
  private final WindowContext _windowContext;

  public PreviewTransformedDataActionListener(WindowContext windowContext,
      TransformerJobBuilderPresenter transformerJobBuilderPresenter, AnalysisJobBuilder analysisJobBuilder,
      TransformerJobBuilder<?> transformerJobBuilder) {
    _windowContext = windowContext;
    _transformerJobBuilderPresenter = transformerJobBuilderPresenter;
    _analysisJobBuilder = analysisJobBuilder;
    _transformerJobBuilder = transformerJobBuilder;

    final DatastoreCatalog datastoreCatalog = DCConfiguration.get().getDatastoreCatalog();
    final ReferenceDataCatalog referenceDataCatalog = DCConfiguration.get().getReferenceDataCatalog();

    _lifeCycleHelper = new LifeCycleHelper(datastoreCatalog, referenceDataCatalog);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    DataSetWindow window = new DataSetWindow("Preview of transformed dataset", this, _windowContext);
    window.setVisible(true);
  }

  private void initialize(TransformerJobBuilder<?> tjb) {
    Object bean = tjb.getConfigurableBean();
    TransformerBeanDescriptor<?> descriptor = tjb.getDescriptor();
    _lifeCycleHelper.initialize(descriptor, bean);

    Set<ConfiguredPropertyDescriptor> referenceDataProperties = descriptor.getConfiguredPropertiesByType(
        ReferenceData.class, true);
    for (ConfiguredPropertyDescriptor configuredPropertyDescriptor : referenceDataProperties) {
      Object configuredProperty = tjb.getConfiguredProperty(configuredPropertyDescriptor);
      _lifeCycleHelper.initialize(configuredProperty);
    }
  }

  private void close(TransformerJobBuilder<?> tjb) {
    Object bean = tjb.getConfigurableBean();
    TransformerBeanDescriptor<?> descriptor = tjb.getDescriptor();
    _lifeCycleHelper.close(descriptor, bean);

    Set<ConfiguredPropertyDescriptor> referenceDataProperties = descriptor.getConfiguredPropertiesByType(
        ReferenceData.class, true);
    for (ConfiguredPropertyDescriptor configuredPropertyDescriptor : referenceDataProperties) {
      Object configuredProperty = tjb.getConfiguredProperty(configuredPropertyDescriptor);
      _lifeCycleHelper.close(configuredProperty);
    }
  }

  private void buildInputChain(InputColumn<?> inputColumn, List<Column> physicalColumns,
      List<TransformerJobBuilder<?>> transformerJobs) {
    if (inputColumn.isPhysicalColumn()) {
      physicalColumns.add(inputColumn.getPhysicalColumn());
    } else {
      TransformerJobBuilder<?> tjb = _analysisJobBuilder.getOriginatingTransformer(inputColumn);
      if (!transformerJobs.contains(tjb)) {
        transformerJobs.add(tjb);
        List<InputColumn<?>> tjbInputs = tjb.getInputColumns();
        for (InputColumn<?> tjbInput : tjbInputs) {
          buildInputChain(tjbInput, physicalColumns, transformerJobs);
        }
      }
    }
  }

  @Override
  public TableModel call() throws Exception {
    if (_transformerJobBuilderPresenter != null) {
      _transformerJobBuilderPresenter.applyPropertyValues();
    }

    final List<TransformerJobBuilder<?>> transformerJobs = new ArrayList<TransformerJobBuilder<?>>();
    transformerJobs.add(_transformerJobBuilder);

    final List<Column> physicalColumns = new ArrayList<Column>();

    for (InputColumn<?> inputColumn : _transformerJobBuilder.getInputColumns()) {
      buildInputChain(inputColumn, physicalColumns, transformerJobs);
    }

    Collections.sort(physicalColumns);

    // reversing the list of transformers should place them in the correct
    // order
    Collections.reverse(transformerJobs);

    final Table[] tables = MetaModelHelper.getTables(physicalColumns);

    if (tables.length != 1) {
      throw new IllegalStateException("Transformer is expected to contain columns originating from 1 table, found "
          + tables.length);
    }

    final Table table = tables[0];

    final DataContextProvider dataContextProvider = _analysisJobBuilder.getDataContextProvider();
    final DataContext dc = dataContextProvider.getDataContext();
    final Query q = dc.query().from(table).select(physicalColumns.toArray(new Column[physicalColumns.size()])).toQuery();
    q.setMaxRows(DEFAULT_PREVIEW_ROWS);

    for (TransformerJobBuilder<?> tjb : transformerJobs) {
      initialize(tjb);
    }

    // getting the output columns can be an expensive call, so we do it
    // upfront in stead of for each row.
    final Map<TransformerJobBuilder<?>, List<MutableInputColumn<?>>> outputColumns = new LinkedHashMap<TransformerJobBuilder<?>, List<MutableInputColumn<?>>>();
    for (TransformerJobBuilder<?> tjb : transformerJobs) {
      List<MutableInputColumn<?>> cols = tjb.getOutputColumns();
      outputColumns.put(tjb, cols);
    }

    final List<InputRow> result = new ArrayList<InputRow>();
    final DataSet dataSet = dc.executeQuery(q);
    int rowNumber = 0;
    while (dataSet.next()) {
      Row row = dataSet.getRow();
      InputRow inputRow = new MetaModelInputRow(rowNumber, row);

      TransformedInputRow resultRow;
      if (inputRow instanceof TransformedInputRow) {
        // re-use existing transformed input row.
        resultRow = (TransformedInputRow) inputRow;
      } else {
        resultRow = new TransformedInputRow(inputRow);
      }

      for (TransformerJobBuilder<?> tjb : transformerJobs) {
        List<MutableInputColumn<?>> cols = outputColumns.get(tjb);
        Object[] output = tjb.getConfigurableBean().transform(resultRow);

        assert cols.size() == output.length;

        for (int i = 0; i < output.length; i++) {
          resultRow.addValue(cols.get(i), output[i]);
        }
      }

      result.add(resultRow);
      rowNumber++;
    }

    // close
    for (TransformerJobBuilder<?> tjb : transformerJobs) {
      close(tjb);
    }

    List<MutableInputColumn<?>> ownOutputColumns = outputColumns.get(_transformerJobBuilder);
    String[] columnNames = new String[_transformerJobBuilder.getInputColumns().size() + ownOutputColumns.size()];
    int column = 0;
    for (InputColumn<?> col : _transformerJobBuilder.getInputColumns()) {
      columnNames[column] = col.getName();
      column++;
    }
    for (InputColumn<?> col : outputColumns.get(_transformerJobBuilder)) {
      columnNames[column] = col.getName();
      column++;
    }

    DefaultTableModel tableModel = new DefaultTableModel(columnNames, result.size());
    int row = 0;
    for (InputRow inputRow : result) {
      column = 0;
      for (InputColumn<?> col : _transformerJobBuilder.getInputColumns()) {
        tableModel.setValueAt(inputRow.getValue(col), row, column);
        column++;
      }
      for (InputColumn<?> col : ownOutputColumns) {
        tableModel.setValueAt(inputRow.getValue(col), row, column);
        column++;
      }

      row++;
    }
    return tableModel;
  }

}
TOP

Related Classes of org.eobjects.datacleaner.actions.PreviewTransformedDataActionListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.