/**
 * Standard {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter}
 * implementation that converts an incoming locale-sensitive String into a <code>java.lang.Decimal
 * </code> object, optionally using a default value or throwing a {@link
 * com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion error occurs.
 *
 * @author Yauheny Mikulski
 * @author Yoav Shapira
 * @since 1.7
 */
public class DecimalLocaleConverter extends BaseLocaleConverter {

  // ----------------------------------------------------- Instance Variables

  /** All logging goes through this logger */
  private static Log log = LogFactory.getLog(DecimalLocaleConverter.class);

  // ----------------------------------------------------------- Constructors

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs. The locale is the default locale for this instance of the Java Virtual Machine
   * and an unlocalized pattern is used for the convertion.
   */
  public DecimalLocaleConverter() {

    this(false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs. The locale is the default locale for this instance of the Java Virtual Machine.
   *
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(boolean locPattern) {

    this(Locale.getDefault(), locPattern);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs. An unlocalized pattern is used for the convertion.
   *
   * @param locale The locale
   */
  public DecimalLocaleConverter(Locale locale) {

    this(locale, false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs.
   *
   * @param locale The locale
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(Locale locale, boolean locPattern) {

    this(locale, (String) null, locPattern);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs. An unlocalized pattern is used for the convertion.
   *
   * @param locale The locale
   * @param pattern The convertion pattern
   */
  public DecimalLocaleConverter(Locale locale, String pattern) {

    this(locale, pattern, false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * throw a {@link com.usemon.lib.org.apache.commons.beanutils.ConversionException} if a conversion
   * error occurs.
   *
   * @param locale The locale
   * @param pattern The convertion pattern
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(Locale locale, String pattern, boolean locPattern) {

    this(null, locale, pattern, locPattern);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs. The locale is the default
   * locale for this instance of the Java Virtual Machine and an unlocalized pattern is used for the
   * convertion.
   *
   * @param defaultValue The default value to be returned
   */
  public DecimalLocaleConverter(Object defaultValue) {

    this(defaultValue, false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs. The locale is the default
   * locale for this instance of the Java Virtual Machine.
   *
   * @param defaultValue The default value to be returned
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(Object defaultValue, boolean locPattern) {

    this(defaultValue, Locale.getDefault(), locPattern);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs. An unlocalized pattern is used
   * for the convertion.
   *
   * @param defaultValue The default value to be returned
   * @param locale The locale
   */
  public DecimalLocaleConverter(Object defaultValue, Locale locale) {

    this(defaultValue, locale, false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs.
   *
   * @param defaultValue The default value to be returned
   * @param locale The locale
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(Object defaultValue, Locale locale, boolean locPattern) {

    this(defaultValue, locale, null, locPattern);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs. An unlocalized pattern is used
   * for the convertion.
   *
   * @param defaultValue The default value to be returned
   * @param locale The locale
   * @param pattern The convertion pattern
   */
  public DecimalLocaleConverter(Object defaultValue, Locale locale, String pattern) {

    this(defaultValue, locale, pattern, false);
  }

  /**
   * Create a {@link com.usemon.lib.org.apache.commons.beanutils.locale.LocaleConverter} that will
   * return the specified default value if a conversion error occurs.
   *
   * @param defaultValue The default value to be returned
   * @param locale The locale
   * @param pattern The convertion pattern
   * @param locPattern Indicate whether the pattern is localized or not
   */
  public DecimalLocaleConverter(
      Object defaultValue, Locale locale, String pattern, boolean locPattern) {

    super(defaultValue, locale, pattern, locPattern);
  }

  // --------------------------------------------------------- Methods

  /**
   * Convert the specified locale-sensitive input object into an output object of the specified
   * type.
   *
   * @param value The input object to be converted
   * @param pattern The pattern is used for the convertion
   * @exception ConversionException if conversion cannot be performed successfully
   */
  protected Object parse(Object value, String pattern) throws ParseException {
    // DecimalFormat is not thread safe so best to construct one each time
    DecimalFormat formatter = (DecimalFormat) DecimalFormat.getInstance(locale);
    // if some constructors default pattern to null, it makes only sense to handle null pattern
    // gracefully
    if (pattern != null) {
      if (locPattern) {
        formatter.applyLocalizedPattern(pattern);
      } else {
        formatter.applyPattern(pattern);
      }
    } else {
      log.warn("No pattern provided, using default.");
    }

    return formatter.parse((String) value);
  }
}
Example #2
0
/**
 * Create a <code>SAXParser</code> based on the underlying Xerces version. Currently, Xerces 2.3 and
 * up doesn't implement schema validation the same way 2.1 was. In other to support schema
 * validation in a portable way between parser, some features/properties need to be set.
 *
 * @since 1.6
 */
public class XercesParser {

  /** The Log to which all SAX event related logging calls will be made. */
  protected static Log log = LogFactory.getLog("org.apache.commons.digester.Digester.sax");

  /** The JAXP 1.2 property required to set up the schema location. */
  private static final String JAXP_SCHEMA_SOURCE =
      "http://java.sun.com/xml/jaxp/properties/schemaSource";

  /** The JAXP 1.2 property to set up the schemaLanguage used. */
  protected static String JAXP_SCHEMA_LANGUAGE =
      "http://java.sun.com/xml/jaxp/properties/schemaLanguage";

  /** Xerces dynamic validation property */
  protected static String XERCES_DYNAMIC = "http://apache.org/xml/features/validation/dynamic";

  /** Xerces schema validation property */
  protected static String XERCES_SCHEMA = "http://apache.org/xml/features/validation/schema";

  /** A <code>float</code> representing the underlying Xerces version */
  protected static float version;

  /** The current Xerces version. */
  protected static String versionNumber = null;

  /**
   * Return the current Xerces version.
   *
   * @return the current Xerces version.
   */
  private static String getXercesVersion() {
    // If for some reason we can't get the version, set it to 1.0.
    String versionNumber = "1.0";
    try {
      // Use reflection to avoid a build dependency with Xerces.
      Class versionClass = Class.forName("org.apache.xerces.impl.Version");
      // Will return Xerces-J 2.x.0
      Method method = versionClass.getMethod("getVersion", (Class[]) null);
      String version = (String) method.invoke(null, (Object[]) null);
      versionNumber = version.substring("Xerces-J".length(), version.lastIndexOf("."));
    } catch (Exception ex) {
      // Do nothing.
    }
    return versionNumber;
  }

  /**
   * Create a <code>SAXParser</code> based on the underlying <code>Xerces</code> version.
   *
   * @param properties parser specific properties/features
   * @return an XML Schema/DTD enabled <code>SAXParser</code>
   */
  public static SAXParser newSAXParser(Properties properties)
      throws ParserConfigurationException, SAXException, SAXNotSupportedException {

    SAXParserFactory factory = (SAXParserFactory) properties.get("SAXParserFactory");

    if (versionNumber == null) {
      versionNumber = getXercesVersion();
      version = new Float(versionNumber).floatValue();
    }

    // Note: 2.2 is completely broken (with XML Schema).
    if (version > 2.1) {

      configureXerces(factory);
      return factory.newSAXParser();
    } else {
      SAXParser parser = factory.newSAXParser();
      configureOldXerces(parser, properties);
      return parser;
    }
  }

  /**
   * Configure schema validation as recommended by the JAXP 1.2 spec. The <code>properties</code>
   * object may contains information about the schema local and language.
   *
   * @param properties parser optional info
   */
  private static void configureOldXerces(SAXParser parser, Properties properties)
      throws ParserConfigurationException, SAXNotSupportedException {

    String schemaLocation = (String) properties.get("schemaLocation");
    String schemaLanguage = (String) properties.get("schemaLanguage");

    try {
      if (schemaLocation != null) {
        parser.setProperty(JAXP_SCHEMA_LANGUAGE, schemaLanguage);
        parser.setProperty(JAXP_SCHEMA_SOURCE, schemaLocation);
      }
    } catch (SAXNotRecognizedException e) {
      log.info(parser.getClass().getName() + ": " + e.getMessage() + " not supported.");
    }
  }

  /**
   * Configure schema validation as recommended by the Xerces spec. Both DTD and Schema validation
   * will be enabled simultaneously.
   *
   * <p>NOTE: This method is broken. It is supposed to set up validation against the schema
   * specified in property "schemaLocation", but it doesn't.
   *
   * @param factory SAXParserFactory to be configured
   */
  private static void configureXerces(SAXParserFactory factory)
      throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {

    factory.setFeature(XERCES_DYNAMIC, true);
    factory.setFeature(XERCES_SCHEMA, true);
  }
}