1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 2001, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.impl.dv.xs;
  58. import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
  59. import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
  60. /**
  61. * Represent the schema type "float"
  62. *
  63. * @author Neeraj Bajaj, Sun Microsystems, inc.
  64. * @author Sandy Gao, IBM
  65. *
  66. * @version $Id: FloatDV.java,v 1.6 2003/02/17 13:45:57 sandygao Exp $
  67. */
  68. public class FloatDV extends TypeValidator {
  69. public short getAllowedFacets(){
  70. return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE );
  71. }//getAllowedFacets()
  72. //convert a String to Float form, we have to take care of cases specified in spec like INF, -INF and NaN
  73. public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException {
  74. try{
  75. return new XFloat(content);
  76. } catch (NumberFormatException ex){
  77. throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{content, "float"});
  78. }
  79. }//getActualValue()
  80. // Can't call Float#compareTo method, because it's introduced in jdk 1.2
  81. public int compare(Object value1, Object value2){
  82. return ((XFloat)value1).compareTo((XFloat)value2);
  83. }//compare()
  84. private static final class XFloat {
  85. private float value;
  86. public XFloat(String s) throws NumberFormatException {
  87. try {
  88. value = Float.parseFloat(s);
  89. }
  90. catch ( NumberFormatException nfe ) {
  91. if ( s.equals("INF") ) {
  92. value = Float.POSITIVE_INFINITY;
  93. }
  94. else if ( s.equals("-INF") ) {
  95. value = Float.NEGATIVE_INFINITY;
  96. }
  97. else if ( s.equals("NaN" ) ) {
  98. value = Float.NaN;
  99. }
  100. else {
  101. throw nfe;
  102. }
  103. }
  104. }
  105. public boolean equals(Object val) {
  106. if (val == this)
  107. return true;
  108. if (!(val instanceof XFloat))
  109. return false;
  110. XFloat oval = (XFloat)val;
  111. // NOTE: we don't distinguish 0.0 from -0.0
  112. if (value == oval.value)
  113. return true;
  114. if (value != value && oval.value != oval.value)
  115. return true;
  116. return false;
  117. }
  118. private int compareTo(XFloat val) {
  119. float oval = val.value;
  120. // this < other
  121. if (value < oval)
  122. return -1;
  123. // this > other
  124. if (value > oval)
  125. return 1;
  126. // this == other
  127. // NOTE: we don't distinguish 0.0 from -0.0
  128. if (value == oval)
  129. return 0;
  130. // one of the 2 values or both is/are NaN(s)
  131. if (value != value) {
  132. // this = NaN = other
  133. if (oval != oval)
  134. return 0;
  135. // this is NaN <> other
  136. return INDETERMINATE;
  137. }
  138. // other is NaN <> this
  139. return INDETERMINATE;
  140. }
  141. private String canonical;
  142. public synchronized String toString() {
  143. if (canonical == null) {
  144. if (value == Float.POSITIVE_INFINITY)
  145. canonical = "INF";
  146. else if (value == Float.NEGATIVE_INFINITY)
  147. canonical = "-INF";
  148. else if (value != value)
  149. canonical = "NaN";
  150. // NOTE: we don't distinguish 0.0 from -0.0
  151. else if (value == 0)
  152. canonical = "0.0E1";
  153. else {
  154. // REVISIT: use the java algorithm for now, because we
  155. // don't know what to output for 1.1f (which is no
  156. // actually 1.1)
  157. canonical = Float.toString(value);
  158. // if it contains 'E', then it should be a valid schema
  159. // canonical representation
  160. if (canonical.indexOf('E') == -1) {
  161. int len = canonical.length();
  162. // at most 3 longer: E, -, 9
  163. char[] chars = new char[len+3];
  164. canonical.getChars(0, len, chars, 0);
  165. // expected decimal point position
  166. int edp = chars[0] == '-' ? 2 : 1;
  167. // for non-zero integer part
  168. if (value >= 1 || value <= -1) {
  169. // decimal point position
  170. int dp = canonical.indexOf('.');
  171. // move the digits: ddd.d --> d.ddd
  172. for (int i = dp; i > edp; i--) {
  173. chars[i] = chars[i-1];
  174. }
  175. chars[edp] = '.';
  176. // trim trailing zeros: d00.0 --> d.000 --> d.
  177. while (chars[len-1] == '0')
  178. len--;
  179. // add the last zero if necessary: d. --> d.0
  180. if (chars[len-1] == '.')
  181. len++;
  182. // append E: d.dd --> d.ddE
  183. chars[len++] = 'E';
  184. // how far we shifted the decimal point
  185. int shift = dp - edp;
  186. // append the exponent --> d.ddEd
  187. // the exponent is at most 7
  188. chars[len++] = (char)(shift + '0');
  189. }
  190. else {
  191. // non-zero digit point
  192. int nzp = edp + 1;
  193. // skip zeros: 0.003
  194. while (chars[nzp] == '0')
  195. nzp++;
  196. // put the first non-zero digit to the left of '.'
  197. chars[edp-1] = chars[nzp];
  198. chars[edp] = '.';
  199. // move other digits (non-zero) to the right of '.'
  200. for (int i = nzp+1, j = edp+1; i < len; i++, j++)
  201. chars[j] = chars[i];
  202. // adjust the length
  203. len -= nzp - edp;
  204. // append 0 if nessary: 0.03 --> 3. --> 3.0
  205. if (len == edp + 1)
  206. chars[len++] = '0';
  207. // append E-: d.dd --> d.ddE-
  208. chars[len++] = 'E';
  209. chars[len++] = '-';
  210. // how far we shifted the decimal point
  211. int shift = nzp - edp;
  212. // append the exponent --> d.ddEd
  213. // the exponent is at most 3
  214. chars[len++] = (char)(shift + '0');
  215. }
  216. canonical = new String(chars, 0, len);
  217. }
  218. }
  219. }
  220. return canonical;
  221. }
  222. }
  223. } // class FloatDV