Package org.eobjects.datacleaner.widgets.visualization

Source Code of org.eobjects.datacleaner.widgets.visualization.VisualizeJobGraph

/**
* 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.widgets.visualization;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Collection;
import java.util.List;

import javax.swing.Icon;
import javax.swing.JComponent;

import org.apache.commons.collections15.Predicate;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.functors.TruePredicate;
import org.eobjects.analyzer.data.InputColumn;
import org.eobjects.analyzer.job.FilterOutcome;
import org.eobjects.analyzer.job.InputColumnSinkJob;
import org.eobjects.analyzer.job.InputColumnSourceJob;
import org.eobjects.analyzer.job.Outcome;
import org.eobjects.analyzer.job.OutcomeSinkJob;
import org.eobjects.analyzer.job.OutcomeSourceJob;
import org.eobjects.analyzer.job.builder.AbstractBeanJobBuilder;
import org.eobjects.analyzer.job.builder.AnalysisJobBuilder;
import org.eobjects.analyzer.job.builder.AnalyzerJobBuilder;
import org.eobjects.analyzer.job.builder.FilterJobBuilder;
import org.eobjects.analyzer.job.builder.MergedOutcomeJobBuilder;
import org.eobjects.analyzer.job.builder.RowProcessingAnalyzerJobBuilder;
import org.eobjects.analyzer.job.builder.TransformerJobBuilder;
import org.eobjects.analyzer.util.SourceColumnFinder;
import org.eobjects.datacleaner.panels.DCPanel;
import org.eobjects.datacleaner.util.IconUtils;
import org.eobjects.datacleaner.util.ImageManager;
import org.eobjects.datacleaner.util.LabelUtils;

import edu.uci.ics.jung.algorithms.layout.StaticLayout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.Context;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;

public final class VisualizeJobGraph {

  private static final long serialVersionUID = 1L;
  private static final ImageManager imageManager = ImageManager.getInstance();

  private VisualizeJobGraph() {
    // prevent instantiation
  }

  public static JComponent create(final AnalysisJobBuilder analysisJobBuilder, final boolean displayColumns,
      final boolean displayOutcomes) {
    final DirectedGraph<Object, VisualizeJobLink> graph = new DirectedSparseGraph<Object, VisualizeJobLink>();

    final SourceColumnFinder sourceColumnFinder = new SourceColumnFinder();
    sourceColumnFinder.addSources(analysisJobBuilder);

    final List<TransformerJobBuilder<?>> tjbs = analysisJobBuilder.getTransformerJobBuilders();
    for (TransformerJobBuilder<?> tjb : tjbs) {
      addGraphNodes(graph, sourceColumnFinder, tjb, displayColumns, displayOutcomes);
    }

    final List<AnalyzerJobBuilder<?>> ajbs = analysisJobBuilder.getAnalyzerJobBuilders();
    for (AnalyzerJobBuilder<?> ajb : ajbs) {
      if (ajb instanceof RowProcessingAnalyzerJobBuilder) {
        RowProcessingAnalyzerJobBuilder<?> rpajb = (RowProcessingAnalyzerJobBuilder<?>) ajb;
        addGraphNodes(graph, sourceColumnFinder, rpajb, displayColumns, displayOutcomes);
      } else {
        // TODO: Add support for explorers
      }
    }

    final List<FilterJobBuilder<?, ?>> fjbs = analysisJobBuilder.getFilterJobBuilders();
    for (FilterJobBuilder<?, ?> fjb : fjbs) {
      addGraphNodes(graph, sourceColumnFinder, fjb, displayColumns, displayOutcomes);
    }

    if (graph.getVertexCount() == 0) {
      graph.addVertex("No components in job");
    }

    final VisualizeJobLayoutTransformer layoutTransformer = new VisualizeJobLayoutTransformer(graph);
    final Dimension preferredSize = layoutTransformer.getPreferredSize();
    final StaticLayout<Object, VisualizeJobLink> layout = new StaticLayout<Object, VisualizeJobLink>(graph,
        layoutTransformer, preferredSize);

    Collection<Object> vertices = graph.getVertices();
    for (Object vertex : vertices) {
      // manually initialize all vertices
      layout.transform(vertex);
    }
    if (!layoutTransformer.isTransformed()) {
      throw new IllegalStateException("Layout transformer was never invoked!");
    }

    final VisualizationViewer<Object, VisualizeJobLink> visualizationViewer = new VisualizationViewer<Object, VisualizeJobLink>(
        layout);
    visualizationViewer.setSize(preferredSize);

    final RenderContext<Object, VisualizeJobLink> renderContext = visualizationViewer.getRenderContext();

    final DefaultModalGraphMouse<Object, Integer> graphMouse = new DefaultModalGraphMouse<Object, Integer>();
    graphMouse.setMode(ModalGraphMouse.Mode.PICKING);
    visualizationViewer.setGraphMouse(graphMouse);

    // render labels
    renderContext.setVertexLabelTransformer(new Transformer<Object, String>() {
      @Override
      public String transform(Object obj) {
        if (obj instanceof InputColumn) {
          return ((InputColumn<?>) obj).getName();
        }
        if (obj instanceof AbstractBeanJobBuilder) {
          return LabelUtils.getLabel((AbstractBeanJobBuilder<?, ?, ?>) obj);
        }
        if (obj instanceof FilterOutcome) {
          return ((FilterOutcome) obj).getCategory().name();
        }
        if (obj instanceof MergedOutcomeJobBuilder) {
          return LabelUtils.getLabel((MergedOutcomeJobBuilder) obj);
        }
        return obj.toString();
      }
    });

    // render arrows
    final Predicate<Context<Graph<Object, VisualizeJobLink>, VisualizeJobLink>> edgeArrowPredicate = TruePredicate
        .getInstance();
    renderContext.setEdgeArrowPredicate(edgeArrowPredicate);

    // render icons
    renderContext.setVertexIconTransformer(new Transformer<Object, Icon>() {

      @Override
      public Icon transform(Object obj) {
        if (obj instanceof InputColumn) {
          return imageManager.getImageIcon("images/model/column.png", IconUtils.ICON_SIZE_SMALL);
        }
        if (obj instanceof AbstractBeanJobBuilder) {
          return IconUtils.getDescriptorIcon(((AbstractBeanJobBuilder<?, ?, ?>) obj).getDescriptor());
        }
        if (obj instanceof FilterOutcome) {
          return imageManager.getImageIcon("images/component-types/filter-outcome.png", IconUtils.ICON_SIZE_SMALL);
        }
        if (obj instanceof MergedOutcomeJobBuilder) {
          return imageManager.getImageIcon("images/component-types/merged-outcome.png", IconUtils.ICON_SIZE_SMALL);
        }
        return imageManager.getImageIcon("images/status/error.png");
      }
    });

    DCPanel panel = new DCPanel();
    panel.setPreferredSize(preferredSize);
    panel.setLayout(new BorderLayout());
    panel.add(visualizationViewer, BorderLayout.CENTER);
    return panel;
  }

  private static void addGraphNodes(Graph<Object, VisualizeJobLink> g, SourceColumnFinder scf, Object item,
      boolean displayColumns, boolean displayFilterOutcomes) {
    if (!displayColumns && item instanceof InputColumn) {
      return;
    } else if (!displayFilterOutcomes && item instanceof FilterOutcome) {
      return;
    }
    if (!g.containsVertex(item)) {

      g.addVertex(item);

      if (item instanceof InputColumnSinkJob) {
        InputColumn<?>[] inputColumns = ((InputColumnSinkJob) item).getInput();
        for (InputColumn<?> inputColumn : inputColumns) {
          if (displayColumns) {
            // add the column itself
            addGraphNodes(g, scf, inputColumn, displayColumns, displayFilterOutcomes);
            addEdge(g, inputColumn, item);
          } else {
            // add the origin of the column
            if (inputColumn.isVirtualColumn()) {
              InputColumnSourceJob source = scf.findInputColumnSource(inputColumn);
              if (source != null) {
                addGraphNodes(g, scf, source, displayColumns, displayFilterOutcomes);
                addEdge(g, source, item);
              }
            }
          }
        }
      }

      if (item instanceof FilterOutcome) {
        OutcomeSourceJob source = scf.findOutcomeSource((FilterOutcome) item);
        if (source != null) {
          addGraphNodes(g, scf, source, displayColumns, displayFilterOutcomes);
          addEdge(g, source, item);
        }
      }

      if (item instanceof OutcomeSinkJob) {
        Outcome[] requirements = ((OutcomeSinkJob) item).getRequirements();
        if (requirements != null && requirements.length > 0) {
          for (Outcome req : requirements) {
            if (displayFilterOutcomes) {
              // add the filter outcome itself
              addGraphNodes(g, scf, req, displayColumns, displayFilterOutcomes);
              addEdge(g, req, item);
            } else {
              // add the origin of the filter outcome
              OutcomeSourceJob source = scf.findOutcomeSource(req);
              if (source != null) {
                addGraphNodes(g, scf, source, displayColumns, displayFilterOutcomes);
                addEdge(g, source, item);
              }
            }
          }
        }
      }

      if (item instanceof InputColumn) {
        InputColumn<?> inputColumn = (InputColumn<?>) item;
        if (inputColumn.isVirtualColumn()) {
          InputColumnSourceJob source = scf.findInputColumnSource(inputColumn);
          if (source != null) {
            addGraphNodes(g, scf, source, displayColumns, displayFilterOutcomes);
            addEdge(g, source, item);
          }
        }
      }
    }
  }

  private static void addEdge(Graph<Object, VisualizeJobLink> g, Object from, Object to) {
    VisualizeJobLink link = new VisualizeJobLink(from, to);
    if (!g.containsEdge(link)) {
      g.addEdge(link, from, to, EdgeType.DIRECTED);
    }
  }
}
TOP

Related Classes of org.eobjects.datacleaner.widgets.visualization.VisualizeJobGraph

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.