blob: 01f6e48c48fd9cf726fb770887945f87c66ea159 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Standards for Technology in Automotive Retail and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Carver - initial API and implementation
* Jesper Steen Moller - bug 283404 - fixed locale
* Mukul Gandhi - bug 280798 - PsychoPath support for JDK 1.4
*******************************************************************************/
package org.eclipse.wst.xml.xpath2.processor.internal.types;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.FieldPosition;
import java.util.Locale;
/**
* This is an XPath specific implementation of DecimalFormat to handle
* some of the xpath specific formatting requirements. Specifically
* it allows for E# to be represented to indicate that the exponent value
* is optional. Otherwise all existing DecimalFormat patterns are handled
* as is.
* @author dcarver
* @see 1.1
*
*/
public class XPathDecimalFormat extends DecimalFormat {
/**
*
*/
private static final long serialVersionUID = -8229885955864187400L;
private static final String NEG_INFINITY = "-INF";
private static final String POS_INFINITY = "INF";
public XPathDecimalFormat(String pattern) {
// Xpath hardcodes this to US locale
super(pattern, new DecimalFormatSymbols(Locale.US));
}
/**
* Formats the string dropping a Zero Exponent Value if it exists.
* @param obj
* @return
*/
public String xpathFormat(Object obj) {
return formatXPath(obj);
}
private String formatXPath(Object obj) {
String curPattern = toPattern();
String newPattern = curPattern.replaceAll("E0", "");
if (obj instanceof Float) {
return formatFloatValue(obj, curPattern, newPattern);
}
if (obj instanceof Double) {
return formatDoubleValue(obj, curPattern, newPattern);
}
return super.format(obj, new StringBuffer(), new FieldPosition(0)).toString();
}
private String formatDoubleValue(Object obj, String curPattern,
String newPattern) {
Double doubleValue = (Double) obj;
if (isDoubleNegativeInfinity(doubleValue)) {
return NEG_INFINITY;
}
if (isDoublePositiveInfinity(doubleValue)) {
return POS_INFINITY;
}
doubleXPathPattern(obj, curPattern, newPattern);
return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
}
private void doubleXPathPattern(Object obj, String curPattern,
String newPattern) {
BigDecimal doubValue = new BigDecimal((((Double) obj)).doubleValue());
BigDecimal minValue = new BigDecimal("-1E6");
BigDecimal maxValue = new BigDecimal("1E6");
if (doubValue.compareTo(minValue) > 0 && doubValue.compareTo(maxValue) < 0) {
applyPattern(newPattern);
} else { //if (doubValue.compareTo(minValue) < 0) {
applyPattern(curPattern.replaceAll("0\\.#", "0.0"));
}
}
private boolean isDoublePositiveInfinity(Double doubleValue) {
return doubleValue.doubleValue() == Double.POSITIVE_INFINITY;
}
private boolean isDoubleNegativeInfinity(Double doubleValue) {
return doubleValue.doubleValue() == Double.NEGATIVE_INFINITY;
}
private String formatFloatValue(Object obj, String curPattern,
String newPattern) {
Float floatValue = (Float) obj;
if (isFloatNegInfinity(floatValue)) {
return NEG_INFINITY;
}
if (isFloatPosInfinity(floatValue)) {
return POS_INFINITY;
}
floatXPathPattern(curPattern, newPattern, floatValue);
return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
}
private boolean isFloatPosInfinity(Float floatValue) {
return floatValue.floatValue() == Float.POSITIVE_INFINITY;
}
private boolean isFloatNegInfinity(Float floatValue) {
return floatValue.floatValue() == Float.NEGATIVE_INFINITY;
}
private void floatXPathPattern(String curPattern, String newPattern,
Float floatValue) {
if (floatValue.floatValue() > -1E6f && floatValue.floatValue() < 1E6f) {
applyPattern(newPattern);
} else if (floatValue.floatValue() <= -1E6f) {
applyPattern(curPattern.replaceAll("0\\.#", "0.0" ));
}
}
}