Package com.google.visualization.datasource.datatable

Source Code of com.google.visualization.datasource.datatable.ValueFormatter

// Copyright 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.visualization.datasource.datatable;

import com.google.common.collect.Maps;
import com.google.visualization.datasource.base.BooleanFormat;
import com.google.visualization.datasource.base.LocaleUtil;
import com.google.visualization.datasource.base.TextFormat;
import com.google.visualization.datasource.datatable.value.BooleanValue;
import com.google.visualization.datasource.datatable.value.DateTimeValue;
import com.google.visualization.datasource.datatable.value.DateValue;
import com.google.visualization.datasource.datatable.value.NumberValue;
import com.google.visualization.datasource.datatable.value.TextValue;
import com.google.visualization.datasource.datatable.value.TimeOfDayValue;
import com.google.visualization.datasource.datatable.value.Value;
import com.google.visualization.datasource.datatable.value.ValueType;

import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.text.UFormat;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

import java.text.ParseException;
import java.util.Date;
import java.util.Map;


/**
* Formats a {@link Value}, or parses a string to create a {@link Value}.
* An instance of this class can be created using the
* {@link #createFromPattern(ValueType, String, ULocale)} method, and can then use the format
* and/or parse.
*
* The class also supplies a set of default patterns per {@link ValueType}. The default patterns
* can be used for parsing/formatting values when there is no specified pattern.
* Otherwise, create a class instance by specifying a pattern and locale.
*
* Note: This class is not thread safe since it uses {@code UFormat}.
*
* @author Yonatan B.Y.
*/

public class ValueFormatter {

  /**
   * A uFormat that does the actual formatting.
   */
  private UFormat uFormat;

  /**
   * The underlying pattern for the {@code UFormat}.
   */
  private String pattern;

  /**
   * The locale used for the UFormatter.
   */
  private ULocale locale;

  /**
   * The {@code ValueType}.
   */
  private ValueType type;

  /**
   * The default pattern for parsing a string to a text value.
   *
   * @see com.google.visualization.datasource.datatable.value.TextValue
   */
  private static final String DEFAULT_TEXT_DUMMY_PATTERN = "dummy";

  /**
   * The default pattern for parsing a string to a date time value.
   *
   * @see DateTimeValue
   */
  private static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

  /**
   * The default pattern for parsing a string to a date value.
   *
   * @see DateValue
   */
  private static final String DEFAULT_DATE_PATTERNS = "yyyy-MM-dd";

  /**
   * The default pattern for parsing a string to a time of day value.
   *
   * @see TimeOfDayValue
   */
  private static final String DEFAULT_TIMEOFDAY_PATTERN = "HH:mm:ss";

  /**
   * The default pattern for parsing a string to a boolean value.
   *
   * @see BooleanValue
   */
  private static final String DEFAULT_BOOLEAN_PATTERN = "true:false";

  /**
   * The default pattern for parsing a string to a number value.
   *
   * @see NumberValue
   */
  private static final String DEFAULT_NUMBER_PATTERN = "";

  /**
   * Private constructor that constructs an instance of this class from a UFormat.
   * Use {@link #createFromPattern(ValueType, String, ULocale)} to create an instance.
   */
  private ValueFormatter(String pattern, UFormat uFormat, ValueType type, ULocale locale) {
    this.pattern = pattern;
    this.uFormat = uFormat;
    this.type = type;
    this.locale = locale;
  }

  /**
   * Creates a formatter for the given value type with the given pattern string and locale.
   * If the pattern is illegal returns null.
   * If pattern is null, uses the first default pattern for the given type.
   * If ulocale is null, uses the default locale return by {@code LocaleUtil#getDefaultLocale}.
   *
   * @param type The column value type.
   * @param pattern The string pattern representing the formatter pattern.
   * @param locale The ULocale of the formatter.
   *
   * @return A formatter for the given type, pattern and locale, or null if the pattern is illegal.
   */
  public static ValueFormatter createFromPattern(ValueType type, String pattern, ULocale locale) {
    UFormat uFormat = null;
    if (pattern == null) {
      pattern = getDefaultPatternByType(type);
    }

    if (locale == null) {
      locale = LocaleUtil.getDefaultLocale();
    }

    // For whichever formatter is created, try to format some arbitrary value, and see if an
    // exception was thrown. If it was thrown, conclude the pattern was illegal, and return null.
    try {
      switch (type) {
        case BOOLEAN:
          uFormat = new BooleanFormat(pattern);
          uFormat.format(BooleanValue.TRUE.getObjectToFormat());
          break;
        case TEXT:
          // Dummy format so no need to check it for problems.
          uFormat = new TextFormat();
          break;
        case DATE:
          uFormat = new SimpleDateFormat(pattern, locale);
          ((SimpleDateFormat) uFormat).setTimeZone(TimeZone.getTimeZone("GMT"));
          uFormat.format(new DateValue(1995, 7, 3).getObjectToFormat());
          break;
        case TIMEOFDAY:
          uFormat = new SimpleDateFormat(pattern, locale);
          ((SimpleDateFormat) uFormat).setTimeZone(TimeZone.getTimeZone("GMT"));
          uFormat.format(new TimeOfDayValue(2, 59, 12, 123).getObjectToFormat());
          break;
        case DATETIME:
          uFormat = new SimpleDateFormat(pattern, locale);
          ((SimpleDateFormat) uFormat).setTimeZone(TimeZone.getTimeZone("GMT"));
          uFormat.format(new DateTimeValue(1995, 7, 3, 2, 59, 12, 123).getObjectToFormat());
          break;
        case NUMBER:
          DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
          uFormat = new DecimalFormat(pattern, symbols);
          uFormat.format(new NumberValue(-12.3).getObjectToFormat());
          break;
      }
    } catch (RuntimeException e) {
      // The formatter is illegal return null.
      return null;
    }
    return new ValueFormatter(pattern, uFormat, type, locale);
  }

  /**
   * Creates a default formatter for the specified value type and locale.
   * If locale is null, uses the default locale returned by {@code LocaleUtil#getDefaultLocale}.
   *
   * @param type The value type.
   * @param locale The data table locale.
   *
   * @return A default formatter for the given type and locale.
   */
  public static ValueFormatter createDefault(ValueType type, ULocale locale) {
    String pattern = getDefaultPatternByType(type);
    return createFromPattern(type, pattern, locale);
  }

  /**
   * Creates default formatters for all the value types for the specified locale.
   * Returns a map of default formatters by type.
   * The map can be used for iterating over a data table and parsing/formatting its values.
   *
   * @param locale The data table locale.
   *
   * @return A map of default formatters by type with the given locale.
   */
  public static Map<ValueType, ValueFormatter> createDefaultFormatters(ULocale locale) {
    Map<ValueType, ValueFormatter> foramtters = Maps.newHashMap();
    for (ValueType type : ValueType.values()) {
      foramtters.put(type, createDefault(type, locale));
    }
    return foramtters;
  }

  /**
   * Formats a value to a string, using the given pattern.
   *
   * @param value The value to format.
   *
   * @return The formatted value.
   */
  public String format(Value value) {
    if (value.isNull()) {
      return "";
    }
    return uFormat.format(value.getObjectToFormat());
  }


  /**
   * Creates the corresponding {@code Value} from the given string.
   * If parsing fails, returns a NULL_VALUE for the specified type.
   * For example, if val="3" and type=ValueType.Number, then after successfully parsing
   * the string "3" into the double 3.0 a new NumberValue would
   * be returned with an internal double value = 3.
   *
   * @param val The string to parse.
   *
   * @return A corresponding {@code Value} for the given string. If parsing fails the value would
   * be a NULL_VALUE of the correct {@code ValueType}.
   */
  public Value parse(String val) {
    Value value = null;
    try {
      switch(type) {
        case DATE:
          value = parseDate(val);
          break;
        case TIMEOFDAY:
          value = parseTimeOfDay(val);
          break;
        case DATETIME:
          value = parseDateTime(val);
          break;
        case NUMBER:
          value = parseNumber(val);
          break;
        case BOOLEAN:
          value = parseBoolean(val);
          break;
        case TEXT:
          // do nothing
          value = new TextValue(val);
          break;
      }
    } catch (ParseException pe) {
      value = Value.getNullValueFromValueType(type);
    }
    return value;
  }

  /**
   * Returns the default pattern for the specified value type and index.
   *
   * @param type The value type.
   *
   * @return The default pattern for the specified value type and index.
   */
  private static String getDefaultPatternByType(ValueType type) {
    String defaultPattern;
    switch (type) {
      case TEXT:
        defaultPattern = DEFAULT_TEXT_DUMMY_PATTERN;
        break;
      case DATE:
        defaultPattern = DEFAULT_DATE_PATTERNS;
        break;
      case DATETIME:
        defaultPattern = DEFAULT_DATETIME_PATTERN;
        break;
      case TIMEOFDAY:
        defaultPattern = DEFAULT_TIMEOFDAY_PATTERN;
        break;
      case BOOLEAN:
        defaultPattern = DEFAULT_BOOLEAN_PATTERN;
        break;
      case NUMBER:
        defaultPattern = DEFAULT_NUMBER_PATTERN;
        break;
      default:
        defaultPattern = null;
    }
    return defaultPattern;
  }



  /**
   * Parses a string to a boolean value.
   *
   * @param val The string to parse.
   *
   * @return A boolean value based on the given string.
   *
   * @throws ParseException if val cannot be parsed into a boolean value.
   */
  private BooleanValue parseBoolean(String val) throws ParseException {
    Boolean bool = ((BooleanFormat) uFormat).parse(val);
    return BooleanValue.getInstance(bool);
  }

  /**
   * Parses a string to a number value.
   *
   * @param val The string to parse.
   *
   * @return A number value based on the given string.
   *
   * @throws ParseException If val cannot be parsed into a number value.
   */
  private NumberValue parseNumber(String val) throws ParseException {
    Number n = ((NumberFormat) uFormat).parse(val);
    return new NumberValue(n.doubleValue());
  }

  /**
   * Parses a string to a date time value.
   *
   * @param val The string to parse.
   *
   * @return A date time value based on the given string.
   *
   * @throws ParseException If val cannot be parsed into a date.
   */
  private DateTimeValue parseDateTime(String val) throws ParseException {
    Date date = ((SimpleDateFormat) uFormat).parse(val);
    GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    gc.setTime(date);
    return new DateTimeValue(gc);
  }

  /**
   * Parses a string to a date value.
   *
   * @param val The string to parse.
   *
   * @return A date value based on the given string.
   *
   * @throws ParseException If val cannot be parsed into a date.
   */
  private DateValue parseDate(String val) throws ParseException {
    Date date = ((SimpleDateFormat) uFormat).parse(val);
    GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    gc.setTime(date);
    return new DateValue(gc);
  }

  /**
   * Parses a string to a time of day value.
   *
   * @param val The string to parse.
   *
   * @return A time of day value based on the given string.
   *
   * @throws ParseException If val cannot be parsed into a date.
   */
  private TimeOfDayValue parseTimeOfDay(String val) throws ParseException {
    Date date = ((SimpleDateFormat) uFormat).parse(val);
    GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    gc.setTime(date);
    return new TimeOfDayValue(gc);
  }



  /**
   * Returns the internal <code>UFormat</code> object.
   *
   * @return The internal <code>UFormat</code> object.
   */
  public UFormat getUFormat() {
    return uFormat;
  }

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

  /**
   * Returns the ulocale.
   *
   * @return The ulocale.
   */
  public ULocale getLocale() {
    return locale;
  }

  /**
   * Returns the type.
   *
   * @return The type.
   */
  public ValueType getType() {
    return type;
  }
}
TOP

Related Classes of com.google.visualization.datasource.datatable.ValueFormatter

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.