Package org.pentaho.reporting.designer.core.actions.elements

Source Code of org.pentaho.reporting.designer.core.actions.elements.MorphAction$MorphUndoEntry

/*
* 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) 2009 Pentaho Corporation.  All rights reserved.
*/

package org.pentaho.reporting.designer.core.actions.elements;

import java.awt.event.ActionEvent;
import java.text.DecimalFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;
import javax.swing.Action;

import org.pentaho.reporting.designer.core.actions.AbstractElementSelectionAction;
import org.pentaho.reporting.designer.core.actions.ActionMessages;
import org.pentaho.reporting.designer.core.editor.ReportRenderContext;
import org.pentaho.reporting.designer.core.model.ModelUtility;
import org.pentaho.reporting.designer.core.model.selection.ReportSelectionModel;
import org.pentaho.reporting.designer.core.util.undo.CompoundUndoEntry;
import org.pentaho.reporting.designer.core.util.undo.UndoEntry;
import org.pentaho.reporting.engine.classic.core.AttributeNames;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.ReportAttributeMap;
import org.pentaho.reporting.engine.classic.core.Section;
import org.pentaho.reporting.engine.classic.core.filter.MessageFormatSupport;
import org.pentaho.reporting.engine.classic.core.filter.types.DateFieldType;
import org.pentaho.reporting.engine.classic.core.filter.types.MessageType;
import org.pentaho.reporting.engine.classic.core.filter.types.NumberFieldType;
import org.pentaho.reporting.engine.classic.core.metadata.AttributeMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.ElementType;
import org.pentaho.reporting.engine.classic.core.util.InstanceID;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;

/**
* Todo: Document Me
*
* @author Thomas Morgner
*/
public final class MorphAction extends AbstractElementSelectionAction
{
  private static final String CORE_NAMESPACE = AttributeNames.Core.NAMESPACE;
  private static final String ELEMENT_TYPE_ATTRIBUE = AttributeNames.Core.ELEMENT_TYPE;
  private static final String FIELD_ATTRIBUTE = AttributeNames.Core.FIELD;
  private static final String VALUE_ATTRIBUTE = AttributeNames.Core.VALUE;
  private static final String FORMAT_ATTRIBUTE = AttributeNames.Core.FORMAT_STRING;

  private ElementType targetElementType;

  public MorphAction(final ElementType elementType)
  {
    targetElementType = elementType;
    putValue(Action.NAME, elementType.getMetaData().getDisplayName(Locale.getDefault()));
  }

  /**
   * Invoked when an action occurs.
   */
  public void actionPerformed(final ActionEvent e)
  {
    final ReportSelectionModel selectionModel1 = getSelectionModel();
    if (selectionModel1 == null)
    {
      return;
    }
    final Element[] visualElements = selectionModel1.getSelectedVisualElements();
    if (visualElements.length == 0)
    {
      return;
    }

    final ArrayList<UndoEntry> undos = new ArrayList<UndoEntry>();
    final ElementMetaData targetMetaData = targetElementType.getMetaData();
    for (int i = 0; i < visualElements.length; i++)
    {
      final Element visualElement = visualElements[i];
      if (visualElement instanceof Section)
      {
        continue;
      }
      if (ObjectUtilities.equal(visualElement.getElementTypeName(), targetElementType.getMetaData().getName()))
      {
        continue;
      }

      final ReportAttributeMap oldAttributes = visualElement.getAttributes();

      final ElementMetaData data = visualElement.getMetaData();
      final AttributeMetaData[] datas = data.getAttributeDescriptions();
      for (int j = 0; j < datas.length; j++)
      {
        final AttributeMetaData metaData = datas[j];
        final AttributeMetaData attributeMetaData =
            targetMetaData.getAttributeDescription(metaData.getNameSpace(), metaData.getName());
        if (attributeMetaData == null)
        {
          visualElement.setAttribute(metaData.getNameSpace(), metaData.getName(), null);
          visualElement.setAttributeExpression(metaData.getNameSpace(), metaData.getName(), null);
        }
      }

      visualElement.setElementType(targetElementType);

      // -------------------- manipulate the value and field attributes so that we preserve as much as possible ---------------------  
      // get the source and destination types
      final ElementType srcType = (ElementType) oldAttributes.getAttribute(CORE_NAMESPACE, ELEMENT_TYPE_ATTRIBUE);
      // Check if the source-type is a message field. In that case, we have to map the pattern into a field and
      // format definition
      if (srcType instanceof MessageType)
      {
        final String message = (String) oldAttributes.getAttribute(CORE_NAMESPACE, VALUE_ATTRIBUTE);
        visualElement.setAttribute(CORE_NAMESPACE, VALUE_ATTRIBUTE, null);
        try
        {

          final MessageFormatSupport fmt = new MessageFormatSupport();
          fmt.setFormatString(message);
          final String rawFormat = fmt.getCompiledFormat();
          final MessageFormat msg = new MessageFormat(rawFormat);
          final Format[] subFormats = msg.getFormats();

          if (targetElementType instanceof DateFieldType)
          {
            final int sdf = findFirstDateFormat(subFormats);
            if (sdf != -1)
            {
              final SimpleDateFormat df = (SimpleDateFormat) subFormats[sdf];

              final String[] fields = fmt.getFields();
              visualElement.setAttribute(CORE_NAMESPACE, FIELD_ATTRIBUTE, fields[sdf]);
              visualElement.setAttribute(CORE_NAMESPACE, FORMAT_ATTRIBUTE, df.toPattern());
            }
          }
          else if (targetElementType instanceof NumberFieldType)
          {
            final int sdf = findFirstNumberFormat(subFormats);
            if (sdf != -1)
            {
              final DecimalFormat df = (DecimalFormat) subFormats[sdf];

              final String[] fields = fmt.getFields();
              visualElement.setAttribute(CORE_NAMESPACE, FIELD_ATTRIBUTE, fields[sdf]);
              visualElement.setAttribute(CORE_NAMESPACE, FORMAT_ATTRIBUTE, df.toPattern());
            }
          }
          else
          {
            final String[] fields = fmt.getFields();
            if (fields.length > 0)
            {
              visualElement.setAttribute(CORE_NAMESPACE, FIELD_ATTRIBUTE, fields[0]);
            }
            else
            {
              visualElement.setAttribute(CORE_NAMESPACE, VALUE_ATTRIBUTE, message);
            }
          }
        }
        catch (Exception ex)
        {
          visualElement.setAttribute(CORE_NAMESPACE, VALUE_ATTRIBUTE, message);
        }
      }
      else if (targetElementType instanceof MessageType)
      {
        // validate that these are the correct combination to use this enhanced morphing.
        // This stuff only applies if we're morphing TO a Message Type field
        final String srcField = (String) oldAttributes.getAttribute(CORE_NAMESPACE, FIELD_ATTRIBUTE); // and morphing FROM Number, Date, or Text Type field
        final String formatString = (String) oldAttributes.getAttribute(CORE_NAMESPACE, FORMAT_ATTRIBUTE);
        final StringBuffer buffer = new StringBuffer();
        buffer.append("$(").append(srcField); //$NON-NLS-1$
        if (srcType instanceof NumberFieldType)
        {
          buffer.append(", number"); //$NON-NLS-1$
          if (formatString != null && formatString.length() > 0)
          {
            buffer.append(", ").append(formatString); //$NON-NLS-1$
          }
        }
        else if (srcType instanceof DateFieldType)
        {
          buffer.append(", date"); //$NON-NLS-1$
          if (formatString != null && formatString.length() > 0)
          {
            buffer.append(", ").append(formatString); //$NON-NLS-1$
          }
        }
        buffer.append(")"); //$NON-NLS-1$
        visualElement.setAttribute(CORE_NAMESPACE, VALUE_ATTRIBUTE, buffer.toString());
      }

      final ReportAttributeMap newAttributes = visualElement.getAttributes();
      undos.add(new MorphUndoEntry(visualElement.getObjectID(), oldAttributes, newAttributes));
    }

    getActiveContext().getUndo().addChange(ActionMessages.getString("MorphAction.UndoName"),
        new CompoundUndoEntry(undos.toArray(new UndoEntry[undos.size()])));
  }

  private int findFirstDateFormat(final Format[] formats)
  {
    for (int j = 0; j < formats.length; j++)
    {
      final Format format = formats[j];
      if (format instanceof SimpleDateFormat)
      {
        return j;
      }
    }
    return -1;
  }

  private int findFirstNumberFormat(final Format[] formats)
  {
    for (int j = 0; j < formats.length; j++)
    {
      final Format format = formats[j];
      if (format instanceof DecimalFormat)
      {
        return j;
      }
    }
    return -1;
  }

  private static class MorphUndoEntry implements UndoEntry
  {
    private InstanceID target;
    private ReportAttributeMap oldAttributes;
    private ReportAttributeMap newAttributes;

    private MorphUndoEntry(final InstanceID target,
                           final ReportAttributeMap oldAttributes,
                           final ReportAttributeMap newAttributes)
    {
      this.target = target;
      this.oldAttributes = oldAttributes;
      this.newAttributes = newAttributes;
    }

    public void undo(final ReportRenderContext renderContext)
    {
      final Element element = (Element) ModelUtility.findElementById(renderContext.getReportDefinition(), target);
      final String[] attributeNamespaces = element.getAttributeNamespaces();
      for (int i = 0; i < attributeNamespaces.length; i++)
      {
        final String attributeNamespace = attributeNamespaces[i];
        final String[] attributeNames = element.getAttributeNames(attributeNamespace);
        for (int j = 0; j < attributeNames.length; j++)
        {
          final String attributeName = attributeNames[j];
          element.setAttribute(attributeNamespace, attributeName, null, false);
        }
      }

      final String[] namespaces = oldAttributes.getNameSpaces();
      for (int i = 0; i < namespaces.length; i++)
      {
        final String attributeNamespace = namespaces[i];
        final String[] attributeNames = oldAttributes.getNames(attributeNamespace);
        for (int j = 0; j < attributeNames.length; j++)
        {
          final String attributeName = attributeNames[j];
          element.setAttribute(attributeNamespace, attributeName,
              oldAttributes.getAttribute(attributeNamespace, attributeName), false);
        }
      }
      element.notifyNodePropertiesChanged();
    }

    public void redo(final ReportRenderContext renderContext)
    {
      final Element element = (Element) ModelUtility.findElementById(renderContext.getReportDefinition(), target);
      final String[] attributeNamespaces = element.getAttributeNamespaces();
      for (int i = 0; i < attributeNamespaces.length; i++)
      {
        final String attributeNamespace = attributeNamespaces[i];
        final String[] attributeNames = element.getAttributeNames(attributeNamespace);
        for (int j = 0; j < attributeNames.length; j++)
        {
          final String attributeName = attributeNames[j];
          element.setAttribute(attributeNamespace, attributeName, null, false);
        }
      }

      final String[] namespaces = newAttributes.getNameSpaces();
      for (int i = 0; i < namespaces.length; i++)
      {
        final String attributeNamespace = namespaces[i];
        final String[] attributeNames = newAttributes.getNames(attributeNamespace);
        for (int j = 0; j < attributeNames.length; j++)
        {
          final String attributeName = attributeNames[j];
          element.setAttribute(attributeNamespace, attributeName,
              newAttributes.getAttribute(attributeNamespace, attributeName), false);
        }
      }
      element.notifyNodePropertiesChanged();
    }

    public UndoEntry merge(final UndoEntry newEntry)
    {
      return null;
    }
  }


}
TOP

Related Classes of org.pentaho.reporting.designer.core.actions.elements.MorphAction$MorphUndoEntry

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.