Package org.pentaho.reporting.engine.classic.core.function

Source Code of org.pentaho.reporting.engine.classic.core.function.TextFormatExpression

/*
* 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) 2001 - 2009 Object Refinery Ltd, Pentaho Corporation and Contributors..  All rights reserved.
*/

package org.pentaho.reporting.engine.classic.core.function;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.DataRow;
import org.pentaho.reporting.engine.classic.core.ResourceBundleFactory;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.formatting.FastMessageFormat;
import org.pentaho.reporting.libraries.formula.util.URLEncoder;

/**
* A TextFormatExpression uses a java.text.MessageFormat to concat and format one or more values evaluated from an
* expression, function or report datasource.
* <p/>
* The TextFormatExpression uses the pattern property to define the global format-pattern used when evaluating the
* expression. The dataRow fields used to fill the expressions placeholders are defined in a list of properties where
* the property-names are numbers. The property counting starts at "0".
* <p/>
* The Syntax of the <code>pattern</code> property is explained in the class {@link java.text.MessageFormat}.
* <p/>
* Example:
* <pre>
* <expression name="expr" class="org.pentaho.reporting.engine.classic.core.function.TextFormatExpression">
* <properties>
* <property name="pattern">Invoice for your order from {0, date, EEE, MMM d,
* yyyy}</property>
* <property name="fields[0]">printdate</property>
* </properties>
* </expression>
* </pre>
* <p/>
* The {@link org.pentaho.reporting.engine.classic.core.function.strings.MessageFormatExpression} allows to specify
* named field-references in the pattern, which greatly simplifies the pattern-definition.
*
* @author Thomas Morgner
* @deprecated Use the MessageFormatExpression instead.
*/
public class TextFormatExpression extends AbstractExpression
{
  private static final Log logger = LogFactory.getLog(TextFormatExpression.class);
  /**
   * An ordered list containing the fieldnames used in the expression.
   */
  private ArrayList fields;

  /**
   * A temporary array to reduce the number of object creations.
   */
  private transient Object[] fieldValues;
  /**
   * A temporary array to reduce the number of object creations. This array is used to compute the cache's validity.
   */
  private transient Object[] oldFieldValues;

  /**
   * The current locale. This is used to optimize the expression evaluation.
   */
  private transient Locale locale;
  /**
   * The current message format object.
   */
  private transient FastMessageFormat messageFormat;

  /**
   * The message-format pattern used to compute the result.
   */
  private String pattern;
  /**
   * A flag indicating whether the data read from the fields should be URL encoded.
   */
  private boolean urlEncodeData;
  /**
   * A flag indicating whether the whole result string should be URL encoded.
   */
  private boolean urlEncodeResult;
  /**
   * The byte-encoding used for the URL encoding.
   */
  private String encoding;
  /**
   * A cached result.
   */
  private String cachedResult;

  /**
   * Default constructor, creates a new unnamed TextFormatExpression.
   */
  public TextFormatExpression()
  {
    fields = new ArrayList();
    encoding = "iso-8859-1";
  }

  /**
   * Returns the defined character encoding that is used to transform the Java-Unicode strings into bytes.
   *
   * @return the encoding.
   */
  public String getEncoding()
  {
    return encoding;
  }

  /**
   * Defines the character encoding that is used to transform the Java-Unicode strings into bytes.
   *
   * @param encoding the encoding.
   */
  public void setEncoding(final String encoding)
  {
    if (encoding == null)
    {
      throw new NullPointerException();
    }
    this.encoding = encoding;
  }

  /**
   * Defines, whether the values read from the data-row should be URL encoded. Dates and Number objects are never
   * encoded.
   *
   * @param urlEncode true, if the values from the data-row should be URL encoded before they are passed to the
   *                  MessageFormat, false otherwise.
   */
  public void setUrlEncodeValues(final boolean urlEncode)
  {
    this.urlEncodeData = urlEncode;
  }

  /**
   * Queries, whether the values read from the data-row should be URL encoded.
   *
   * @return true, if the values are encoded, false otherwise.
   */
  public boolean isUrlEncodeValues()
  {
    return urlEncodeData;
  }

  /**
   * Queries, whether the formatted result-string will be URL encoded.
   *
   * @return true, if the formatted result will be encoded, false otherwise.
   */
  public boolean isUrlEncodeResult()
  {
    return urlEncodeResult;
  }

  /**
   * Defines, whether the formatted result-string will be URL encoded.
   *
   * @param urlEncodeResult true, if the formatted result will be encoded, false otherwise.
   */
  public void setUrlEncodeResult(final boolean urlEncodeResult)
  {
    this.urlEncodeResult = urlEncodeResult;
  }

  /**
   * Evaluates the expression by collecting all values defined in the fieldlist from the datarow. The collected values
   * are then parsed and formated by the MessageFormat-object.
   *
   * @return a string containing the pattern inclusive the formatted values from the datarow
   */
  public Object getValue()
  {
    if (fields.isEmpty())
    {
      return getPattern();
    }

    final ResourceBundleFactory factory = getResourceBundleFactory();
    if (messageFormat == null || ObjectUtilities.equal(locale, factory.getLocale()) == false)
    {
      messageFormat = new FastMessageFormat(getPattern(), factory.getLocale());
      this.locale = factory.getLocale();
    }

    try
    {
      if (oldFieldValues == null || oldFieldValues.length != fields.size())
      {
        oldFieldValues = new Object[fields.size()];
      }
      else if (fieldValues != null && fieldValues.length == oldFieldValues.length)
      {
        System.arraycopy(fieldValues, 0, oldFieldValues, 0, fields.size());
      }

      fieldValues = getFieldValues(fieldValues);
      final String result;
      if (cachedResult != null &&
          Arrays.equals(oldFieldValues, fieldValues))
      {
        result = cachedResult;
      }
      else
      {
        result = messageFormat.format(fieldValues);
        cachedResult = result;
      }

      if (isUrlEncodeResult())
      {
        return URLEncoder.encode(result, getEncoding());
      }
      else
      {
        return result;
      }
    }
    catch (UnsupportedEncodingException e)
    {
      TextFormatExpression.logger.debug("Unsupported Encoding: " + encoding);
      return null;
    }
  }

  /**
   * Collects the values of all fields defined in the fieldList.
   *
   * @param retval an optional array that will receive the field values.
   * @return an Object-array containing all defined values from the datarow
   * @throws java.io.UnsupportedEncodingException
   *          if the character encoding is not recognized by the JDK.
   */
  protected Object[] getFieldValues(Object[] retval)
      throws UnsupportedEncodingException
  {
    final int size = fields.size();
    if (retval == null || retval.length != size)
    {
      retval = new Object[size];
    }

    final DataRow dataRow = getDataRow();
    for (int i = 0; i < size; i++)
    {
      final String field = (String) fields.get(i);
      if (field == null)
      {
        retval[i] = null;
        continue;
      }
      final Object fieldValue = dataRow.get(field);
      if (isUrlEncodeValues())
      {
        if (fieldValue == null)
        {
          retval[i] = null;
        }
        else if (fieldValue instanceof Date)
        {
          retval[i] = fieldValue;
        }
        else if (fieldValue instanceof Number)
        {
          retval[i] = fieldValue;
        }
        else if (isUrlEncodeValues())
        {
          retval[i] = URLEncoder.encode(String.valueOf(fieldValue), encoding);
        }
        else
        {
          retval[i] = fieldValue;
        }
      }
      else
      {
        retval[i] = fieldValue;
      }
    }
    return retval;
  }

  /**
   * Returns the pattern defined for this expression.
   *
   * @return the pattern.
   */
  public String getPattern()
  {
    return pattern;
  }

  /**
   * Defines the pattern for this expression. The pattern syntax is defined by the java.text.MessageFormat object and
   * the given pattern string has to be valid according to the rules defined there.
   *
   * @param pattern the pattern string
   */
  public void setPattern(final String pattern)
  {
    if (pattern == null)
    {
      throw new NullPointerException();
    }
    this.messageFormat = null;
    this.pattern = pattern;
    this.cachedResult = null;
  }

  /**
   * Return a completly separated copy of this function. The copy does no longer share any changeable objects with the
   * original function.
   *
   * @return a copy of this function.
   */
  public Expression getInstance()
  {
    final TextFormatExpression tex = (TextFormatExpression) super.getInstance();
    tex.fields = (ArrayList) fields.clone();
    tex.fieldValues = null;
    tex.oldFieldValues = null;
    tex.cachedResult = null;
    return tex;
  }

  /**
   * Defines the field in the field-list at the given index.
   *
   * @param index the position in the list, where the field should be defined.
   * @param field the name of the field.
   */
  public void setField(final int index, final String field)
  {
    if (fields.size() == index)
    {
      fields.add(field);
    }
    else
    {
      fields.set(index, field);
    }
    fieldValues = null;
    oldFieldValues = null;
    cachedResult = null;
  }

  /**
   * Returns the defined field at the given index-position.
   *
   * @param index the position of the field name that should be queried.
   * @return the field name at the given position.
   */
  public String getField(final int index)
  {
    return (String) fields.get(index);
  }

  /**
   * Returns the number of fields defined in this expression.
   *
   * @return the number of fields.
   */
  public int getFieldCount()
  {
    return fields.size();
  }

  /**
   * Returns all defined fields as array of strings.
   *
   * @return all the fields.
   */
  public String[] getField()
  {
    return (String[]) fields.toArray(new String[fields.size()]);
  }

  /**
   * Defines all fields as array. This completely replaces any previously defined fields.
   *
   * @param fields the new list of fields.
   */
  public void setField(final String[] fields)
  {
    this.fields.clear();
    this.fields.addAll(Arrays.asList(fields));
    fieldValues = null;
    oldFieldValues = null;
    cachedResult = null;
  }
}
TOP

Related Classes of org.pentaho.reporting.engine.classic.core.function.TextFormatExpression

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.