Package org.pentaho.reporting.designer.core.editor.structuretree

Source Code of org.pentaho.reporting.designer.core.editor.structuretree.DataReportTree$ReportUpdateHandler

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.reporting.designer.core.editor.structuretree;

import java.awt.datatransfer.Transferable;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import org.pentaho.reporting.designer.core.actions.report.EditParametersAction;
import org.pentaho.reporting.designer.core.actions.report.EditQueryAction;
import org.pentaho.reporting.designer.core.editor.ReportDataChangeListener;
import org.pentaho.reporting.designer.core.editor.ReportDocumentContext;
import org.pentaho.reporting.designer.core.model.selection.DocumentContextSelectionModel;
import org.pentaho.reporting.designer.core.settings.SettingsListener;
import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.designer.core.util.dnd.FieldDescriptionTransferable;
import org.pentaho.reporting.designer.core.util.exceptions.UncaughtExceptionsModel;
import org.pentaho.reporting.engine.classic.core.AbstractReportDefinition;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.CompoundDataFactory;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.ParameterMapping;
import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException;
import org.pentaho.reporting.engine.classic.core.SubReport;
import org.pentaho.reporting.engine.classic.core.designtime.AttributeChange;
import org.pentaho.reporting.engine.classic.core.designtime.AttributeExpressionChange;
import org.pentaho.reporting.engine.classic.core.designtime.StyleChange;
import org.pentaho.reporting.engine.classic.core.designtime.StyleExpressionChange;
import org.pentaho.reporting.engine.classic.core.designtime.SubReportParameterChange;
import org.pentaho.reporting.engine.classic.core.event.ReportModelEvent;
import org.pentaho.reporting.engine.classic.core.event.ReportModelListener;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition;
import org.pentaho.reporting.libraries.base.util.DebugLog;

public class DataReportTree extends AbstractReportTree
{
  private class ReportUpdateHandler implements ReportModelListener, ReportDataChangeListener
  {
    private ReportUpdateHandler()
    {
    }

    public void dataModelChanged(final ReportDocumentContext context)
    {
      final AbstractReportDataTreeModel realModel = getDataTreeModel();
      if (realModel == null)
      {
        return;
      }

      DebugLog.log("Data Changed, Update tree");
      realModel.fireQueryChanged(renderContext.getReportDefinition().getQuery());
    }

    public void nodeChanged(final ReportModelEvent event)
    {
      final AbstractReportDataTreeModel realModel = getDataTreeModel();
      if (realModel == null)
      {
        return;
      }

      try
      {
        if (event.isNodeDeleteEvent())
        {
          handleNodeRemoved(event, realModel);
        }

        if (event.isNodeAddedEvent())
        {
          handleNodeAdded(event, realModel);
        }

        if (event.getType() == ReportModelEvent.NODE_PROPERTIES_CHANGED)
        {
          if (event.getElement() == renderContext.getReportDefinition())
          {
            final Object eventParameter = event.getParameter();
            if (eventParameter instanceof AttributeExpressionChange ||
                eventParameter instanceof StyleChange ||
                eventParameter instanceof StyleExpressionChange)
            {
              // these things have no effect on the data ..
              return;
            }

            if (eventParameter instanceof AttributeChange)
            {
              final AttributeChange attributeChange = (AttributeChange) eventParameter;
              if (AttributeNames.Internal.NAMESPACE.equals(attributeChange.getNamespace()) ||
                  AttributeNames.Internal.QUERY.equals(attributeChange.getName()))
              {

                realModel.fireQueryChanged(attributeChange.getOldValue());
                realModel.fireQueryChanged(attributeChange.getNewValue());
              }
              return;
            }

            if (eventParameter instanceof Expression ||
                eventParameter instanceof ReportParameterDefinition)
            {
              realModel.fireTreeNodeChanged(eventParameter);
            }
            else if (eventParameter instanceof SubReportParameterChange)
            {
              if (realModel instanceof SubReportDataTreeModel)
              {
                final SubReportDataTreeModel subReportDataTreeModel = (SubReportDataTreeModel) realModel;
                realModel.fireTreeStructureChanged(subReportDataTreeModel.getReportParametersNode());
              }
            }
            else
            {
              realModel.fireTreeDataChanged();
            }
          }
          else
          {
            realModel.fireTreeNodeChanged(event.getElement());
          }
        }
      }
      finally
      {
        restoreState();
        expandAfterDataSourceEdit(event);
      }
    }

    private void handleNodeRemoved(final ReportModelEvent event, final AbstractReportDataTreeModel realModel)
    {
      if (event.getElement() == renderContext.getReportDefinition())
      {
        final Object eventParam = event.getParameter();
        if (eventParam instanceof Expression)
        {
          final Expression expression = (Expression) eventParam;
          realModel.fireExpressionRemoved(expression);
        }
        else if (eventParam instanceof ParameterDefinitionEntry)
        {
          final ParameterDefinitionEntry parameter = (ParameterDefinitionEntry) eventParam;
          if (realModel instanceof MasterReportDataTreeModel)
          {
            final MasterReportDataTreeModel masterModel = (MasterReportDataTreeModel) realModel;
            masterModel.fireParameterRemoved(parameter);
          }
        }
        else if (eventParam instanceof DataFactory)
        {
          realModel.fireTreeStructureChanged(realModel.getDataFactoryElement());
        }
        else
        {
          realModel.fireTreeDataChanged();
        }
      }
    }

    private void handleNodeAdded(final ReportModelEvent event, final AbstractReportDataTreeModel realModel)
    {
      if (event.getElement() == renderContext.getReportDefinition())
      {
        final Object eventParam = event.getParameter();
        if (eventParam instanceof Expression)
        {
          final Expression expression = (Expression) eventParam;
          realModel.fireExpressionAdded(expression);
        }
        else if (eventParam instanceof ParameterDefinitionEntry)
        {
          final ParameterDefinitionEntry parameter = (ParameterDefinitionEntry) eventParam;
          if (realModel instanceof MasterReportDataTreeModel)
          {
            final MasterReportDataTreeModel masterModel = (MasterReportDataTreeModel) realModel;
            masterModel.fireParameterAdded(parameter);
          }
        }
        else if (eventParam instanceof DataFactory)
        {
          realModel.fireTreeStructureChanged(realModel.getDataFactoryElement());
        }
        else
        {
          realModel.fireTreeDataChanged();
        }
      }
    }

    private void expandAfterDataSourceEdit(final ReportModelEvent event)
    {
      final Object element = event.getElement();
      if (event.isNodeStructureChanged() == false)
      {
        return;
      }
      if (element instanceof AbstractReportDefinition == false)
      {
        return;
      }
      if (treeModel instanceof AbstractReportDataTreeModel == false)
      {
        return;
      }
      final AbstractReportDataTreeModel dataTreeModel = (AbstractReportDataTreeModel) treeModel;

      final Object parameter = event.getParameter();
      if (parameter instanceof DataFactory)
      {
        SwingUtilities.invokeLater(new ExpandDataFactoryNodesTask(dataTreeModel));
      }
      else if (parameter instanceof Expression)
      {
        SwingUtilities.invokeLater(new ExpandExpressionNodesTask(dataTreeModel));
      }
      else if (parameter instanceof ReportParameterDefinition)
      {
        SwingUtilities.invokeLater(new ExpandParameterDataSourceTask(dataTreeModel));
      }
    }
  }


  private class SettingsChangeHandler implements SettingsListener
  {
    private boolean showIndexColumns;

    private SettingsChangeHandler()
    {
      showIndexColumns = WorkspaceSettings.getInstance().isShowIndexColumns();
    }

    public void settingsChanged()
    {
      // revalidate the data model ..
      if (showIndexColumns != WorkspaceSettings.getInstance().isShowIndexColumns())
      {
        showIndexColumns = WorkspaceSettings.getInstance().isShowIndexColumns();

        final TreeModel model = getModel();
        if (model instanceof AbstractReportDataTreeModel)
        {
          final AbstractReportDataTreeModel realModel = (AbstractReportDataTreeModel) model;
          realModel.fireTreeDataChanged();
          restoreState();
        }
      }
      invalidateLayoutCache();
    }
  }

  private class ExpandDataFactoryNodesTask implements Runnable
  {
    private AbstractReportDataTreeModel treeModel;

    private ExpandDataFactoryNodesTask(final AbstractReportDataTreeModel treeModel)
    {
      this.treeModel = treeModel;
    }

    public void run()
    {
      if (getModel() != treeModel)
      {
        return;
      }

      final CompoundDataFactory compoundDataFactory = treeModel.getDataFactoryElement();
      final int size = compoundDataFactory.size();
      for (int i = 0; i < size; i++)
      {
        final DataFactory df = compoundDataFactory.getReference(i);
        final TreePath path = treeModel.getPathForNode(df);
        if (path == null)
        {
          return;
        }

        expandPath(path);
        final int count = treeModel.getChildCount(df);
        for (int x = 0; x < count; x++)
        {
          final Object child = treeModel.getChild(df, x);
          if (child == null)
          {
            continue;
          }
          final TreePath childPath = path.pathByAddingChild(child);
          expandPath(childPath);
        }
      }
    }
  }


  private class ExpandExpressionNodesTask implements Runnable
  {
    private AbstractReportDataTreeModel treeModel;

    private ExpandExpressionNodesTask(final AbstractReportDataTreeModel treeModel)
    {
      this.treeModel = treeModel;
    }

    public void run()
    {
      if (getModel() != treeModel)
      {
        return;
      }

      final AbstractReportDataTreeModel dataTreeModel = treeModel;
      expandPath(new TreePath(new Object[]{dataTreeModel.getRoot(), dataTreeModel.getReportFunctionNode()}));
    }
  }

  private class ExpandParameterDataSourceTask implements Runnable
  {
    private AbstractReportDataTreeModel treeModel;

    private ExpandParameterDataSourceTask(final AbstractReportDataTreeModel treeModel)
    {
      this.treeModel = treeModel;
    }

    public void run()
    {
      if (getModel() != treeModel)
      {
        return;
      }

      if (treeModel instanceof MasterReportDataTreeModel)
      {
        final MasterReportDataTreeModel dataTreeModel = (MasterReportDataTreeModel) treeModel;
        expandPath(new TreePath(new Object[]{dataTreeModel.getRoot(), dataTreeModel.getReportParametersNode()}));
      }

      if (treeModel instanceof SubReportDataTreeModel)
      {
        final SubReportDataTreeModel dataTreeModel = (SubReportDataTreeModel) treeModel;
        expandPath(new TreePath(new Object[]{dataTreeModel.getRoot(), dataTreeModel.getReportParametersNode()}));
      }
    }
  }


  private class ExpandEnvironmentDataSourceTask implements Runnable
  {
    private AbstractReportDataTreeModel treeModel;

    private ExpandEnvironmentDataSourceTask(final AbstractReportDataTreeModel treeModel)
    {
      this.treeModel = treeModel;
    }

    public void run()
    {
      if (getModel() != treeModel)
      {
        return;
      }

      expandPath(new TreePath(new Object[]{treeModel.getRoot(), treeModel.getReportEnvironmentDataRow()}));
    }
  }


  private class ColumnTransferHandler extends TransferHandler
  {
    /**
     * Creates a <code>Transferable</code> to use as the source for a data transfer. Returns the representation of the
     * data to be transferred, or <code>null</code> if the component's property is <code>null</code>
     *
     * @param c the component holding the data to be transferred; this argument is provided to enable sharing of
     *          <code>TransferHandler</code>s by multiple components
     * @return the representation of the data to be transferred, or <code>null</code> if the property associated with
     *         <code>c</code> is <code>null</code>
     */
    protected Transferable createTransferable(final JComponent c)
    {
      if (c != DataReportTree.this)
      {
        return null;
      }

      final Object node = getSelectionPath().getLastPathComponent();
      if (node instanceof ReportFieldNode)
      {
        final ReportFieldNode field = (ReportFieldNode) node;
        return new FieldDescriptionTransferable(field.getFieldName());
      }
      if (node instanceof ParameterMapping)
      {
        final Object o = getSelectionPath().getParentPath().getLastPathComponent();
        if (o instanceof SubReportParametersNode.ImportParametersNode)
        {
          final ParameterMapping field = (ParameterMapping) node;
          return new FieldDescriptionTransferable(field.getAlias());
        }
      }
      if (node instanceof ParameterDefinitionEntry)
      {
        final ParameterDefinitionEntry field = (ParameterDefinitionEntry) node;
        return new FieldDescriptionTransferable(field.getName());
      }
      if (node instanceof Expression)
      {
        final Expression expression = (Expression) node;
        if (expression.getName() != null)
        {
          return new FieldDescriptionTransferable(expression.getName());
        }
      }
      return null;
    }

    public int getSourceActions(final JComponent c)
    {
      return COPY;
    }
  }

  private class EditQueryDoubleClickHandler extends MouseAdapter
  {
    private EditQueryDoubleClickHandler()
    {
    }

    public void mouseClicked(final MouseEvent e)
    {
      if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
      {
        final TreePath selectionPath = getLeadSelectionPath();
        if (selectionPath == null)
        {
          return;
        }

        try
        {
          final Object selection = selectionPath.getLastPathComponent();
          if (selection instanceof ParameterDefinitionEntry)
          {
            final ParameterDefinitionEntry parameterDefinitionEntry = (ParameterDefinitionEntry) selection;
            EditParametersAction.performEditMasterReportParameters(getReportDesignerContext(), parameterDefinitionEntry);
            return;
          }

          if (selection instanceof ParameterMapping ||
              selection instanceof SubReportParametersNode)
          {
            EditParametersAction.performEditSubReportParameters(getReportDesignerContext());
            return;
          }

          if (selection instanceof DataFactory)
          {
            final EditQueryAction action = new EditQueryAction();
            action.setReportDesignerContext(getReportDesignerContext());
            action.performEdit((DataFactory) selection, null);
            return;
          }

          if (selection instanceof ReportQueryNode)
          {
            final ReportQueryNode queryNode = (ReportQueryNode) selection;
            if (queryNode.isAllowEdit() == false)
            {
              return;
            }
            final EditQueryAction action = new EditQueryAction();
            action.setReportDesignerContext(getReportDesignerContext());
            action.performEdit(queryNode.getDataFactory(), queryNode.getQueryName());
            e.consume();
          }
        }
        catch (ReportDataFactoryException e1)
        {
          UncaughtExceptionsModel.getInstance().addException(e1);
        }

      }
    }
  }

  private ReportDocumentContext renderContext;
  private ReportUpdateHandler updateHandler;

  @SuppressWarnings("FieldCanBeLocal")
  private SettingsChangeHandler settingsChangeHandler;

  public DataReportTree()
  {
    updateHandler = new ReportUpdateHandler();

    setCellRenderer(new StructureTreeCellRenderer());
    setTransferHandler(new ColumnTransferHandler());
    setDragEnabled(true);
    setEditable(false);
    setRootVisible(false);

    addMouseListener(new EditQueryDoubleClickHandler());

    settingsChangeHandler = new SettingsChangeHandler();
    WorkspaceSettings.getInstance().addSettingsListener(settingsChangeHandler);
  }

  public ReportDocumentContext getRenderContext()
  {
    return renderContext;
  }

  protected TreePath getPathForNode(final Object node)
  {
    if (getDataTreeModel() == null)
    {
      return null;
    }

    return getDataTreeModel().getPathForNode(node);
  }

  public void setRenderContext(final ReportDocumentContext renderContext)
  {
    if (this.renderContext != null)
    {
      this.renderContext.getSelectionModel().removeReportSelectionListener(getSelectionHandler());
      this.renderContext.getReportDefinition().removeReportModelListener(updateHandler);
      this.renderContext.removeReportDataChangeListener(updateHandler);
    }
    this.renderContext = renderContext;
    if (this.renderContext != null)
    {
      this.renderContext.getSelectionModel().addReportSelectionListener(getSelectionHandler());
      this.renderContext.getReportDefinition().addReportModelListener(updateHandler);
      this.renderContext.addReportDataChangeListener(updateHandler);
    }
    updateFromRenderContext();
    restoreState();
  }

  protected void updateFromRenderContext()
  {
    try
    {
      setUpdateFromExternalSource(true);

      if (this.renderContext == null)
      {
        setModel(EMPTY_MODEL);
        return;
      }

      final AbstractReportDefinition report = this.renderContext.getReportDefinition();
      final AbstractReportDataTreeModel model;
      if (report instanceof MasterReport)
      {
        model = new MasterReportDataTreeModel(renderContext);
      }
      else if (report instanceof SubReport)
      {
        model = new SubReportDataTreeModel(renderContext);
      }
      else
      {
        setModel(EMPTY_MODEL);
        return;
      }

      setModel(model);

      final DocumentContextSelectionModel selectionModel = renderContext.getSelectionModel();
      final Object[] selectedElements = selectionModel.getSelectedElements();
      final ArrayList<TreePath> selectionPaths = new ArrayList<TreePath>();
      for (int i = 0; i < selectedElements.length; i++)
      {
        final Object o = selectedElements[i];
        final TreePath path = model.getPathForNode(o);
        if (path != null)
        {
          selectionPaths.add(path);
        }
      }
      getSelectionModel().setSelectionPaths(selectionPaths.toArray(new TreePath[selectionPaths.size()]));

      SwingUtilities.invokeLater(new ExpandDataFactoryNodesTask(model));
      SwingUtilities.invokeLater(new ExpandExpressionNodesTask(model));
      SwingUtilities.invokeLater(new ExpandParameterDataSourceTask(model));
      SwingUtilities.invokeLater(new ExpandEnvironmentDataSourceTask(model));
    }
    finally
    {
      setUpdateFromExternalSource(false);
    }
  }

  private AbstractReportDataTreeModel getDataTreeModel()
  {
    final TreeModel model = getModel();
    if (model instanceof AbstractReportDataTreeModel)
    {
      return (AbstractReportDataTreeModel) model;
    }
    return null;
  }
}
TOP

Related Classes of org.pentaho.reporting.designer.core.editor.structuretree.DataReportTree$ReportUpdateHandler

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.