Save This Page
Home » xmlbeans-2.4.0-src » org.apache.xmlbeans.impl.values » [javadoc | source]
    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans.impl.values;
   17   
   18   import org.apache.xmlbeans.SchemaType;
   19   import org.apache.xmlbeans.XmlErrorCodes;
   20   import org.apache.xmlbeans.XmlObject;
   21   import org.apache.xmlbeans.impl.common.ValidationContext;
   22   import org.apache.xmlbeans.impl.common.QNameHelper;
   23   
   24   
   25   import java.math.BigDecimal;
   26   
   27   public abstract class JavaDecimalHolderEx extends JavaDecimalHolder
   28   {
   29       private SchemaType _schemaType;
   30   
   31       public SchemaType schemaType()
   32           { return _schemaType; }
   33   
   34       public JavaDecimalHolderEx(SchemaType type, boolean complex)
   35           { _schemaType = type; initComplexType(complex, false); }
   36   
   37       protected void set_text(String s)
   38       {
   39           if (_validateOnSet())
   40               validateLexical(s, _schemaType, _voorVc);
   41   
   42           BigDecimal v = null;
   43           try {
   44               v = new BigDecimal(s);
   45           }
   46           catch (NumberFormatException e)
   47           {
   48               _voorVc.invalid(XmlErrorCodes.DECIMAL, new Object[] { s });
   49           }
   50   
   51           if (_validateOnSet())
   52               validateValue(v, _schemaType, _voorVc);
   53   
   54           super.set_BigDecimal(v);
   55       }
   56       
   57       protected void set_BigDecimal(BigDecimal v)
   58       {
   59           if (_validateOnSet())
   60               validateValue(v, _schemaType, _voorVc);
   61           super.set_BigDecimal(v);
   62       }
   63       
   64       public static void validateLexical(String v, SchemaType sType, ValidationContext context)
   65       {
   66           JavaDecimalHolder.validateLexical(v, context);
   67           
   68           // check pattern
   69           if (sType.hasPatternFacet())
   70           {
   71               if (!sType.matchPatternFacet(v))
   72               {
   73                   // TODO - describe string and pattern here in error
   74                   context.invalid(XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID,
   75                       new Object[] { "decimal", v, QNameHelper.readable(sType) });
   76               }
   77           }
   78       }
   79       
   80       /**
   81        * Performs facet validation only.
   82        */
   83   
   84       public static void validateValue(BigDecimal v, SchemaType sType, ValidationContext context)
   85       {
   86           // fractional digits
   87           XmlObject fd = sType.getFacet(SchemaType.FACET_FRACTION_DIGITS);
   88           if (fd != null)
   89           {
   90               int scale = ((XmlObjectBase)fd).bigIntegerValue().intValue();
   91               try
   92               {
   93                   // used only for side-effect - this does not change v despite
   94                   // the name of the method
   95                   v.setScale(scale);
   96               }
   97               catch(ArithmeticException e)
   98               {
   99                   // ArithmeticException will be thrown if cannot represent as an Integer
  100                   // with this scale - i.e. would need a fraction which would correspond
  101                   // to digits beyond the allowed number
  102                   context.invalid(XmlErrorCodes.DATATYPE_FRACTION_DIGITS_VALID,
  103                       new Object[] { new Integer(v.scale()), v.toString(), new Integer(scale), QNameHelper.readable(sType) });
  104                   return;
  105               }
  106           }
  107   
  108           // total digits
  109           XmlObject td = sType.getFacet(SchemaType.FACET_TOTAL_DIGITS);
  110           if (td != null)
  111           {
  112               String temp = v.unscaledValue().toString();
  113               int tdf = ((XmlObjectBase)td).bigIntegerValue().intValue();
  114               int origLen = temp.length();
  115               int len = origLen;
  116               if (origLen > 0)
  117               {
  118                   // don't count leading minus
  119                   if (temp.charAt(0) == '-')
  120                   {
  121                       len -= 1;
  122                   }
  123   
  124                   // don't count trailing zeros if we can absorb them into scale
  125                   int insignificantTrailingZeros = 0;
  126                   int vScale = v.scale();
  127                   for(int j = origLen-1;
  128                       temp.charAt(j) == '0' && j > 0 && insignificantTrailingZeros < vScale;
  129                       j--)
  130                   {
  131                       insignificantTrailingZeros++;
  132                   }
  133   
  134                   len -= insignificantTrailingZeros;
  135               }
  136   
  137               if (len > tdf)
  138               {
  139                   context.invalid(XmlErrorCodes.DATATYPE_TOTAL_DIGITS_VALID,
  140                       new Object[] { new Integer(len), v.toString(), new Integer(tdf), QNameHelper.readable(sType) });
  141                   return;
  142               }
  143           }
  144   
  145           // min ex
  146           XmlObject mine = sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
  147           if (mine != null)
  148           {
  149               BigDecimal m = ((XmlObjectBase)mine).bigDecimalValue();
  150               if (v.compareTo(m) <= 0)
  151               {
  152                   context.invalid(XmlErrorCodes.DATATYPE_MIN_EXCLUSIVE_VALID,
  153                       new Object[] { "decimal", v, m, QNameHelper.readable(sType) });
  154                   return;
  155               }
  156           }
  157   
  158           // min in
  159           XmlObject mini = sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
  160           if (mini != null)
  161           {
  162               BigDecimal m = ((XmlObjectBase)mini).bigDecimalValue();
  163               if (v.compareTo(m) < 0)
  164               {
  165                   context.invalid(XmlErrorCodes.DATATYPE_MIN_INCLUSIVE_VALID,
  166                       new Object[] { "decimal", v, m, QNameHelper.readable(sType) });
  167                   return;
  168               }
  169           }
  170   
  171           // max in
  172           XmlObject maxi = sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
  173           if (maxi != null)
  174           {
  175               BigDecimal m = ((XmlObjectBase)maxi).bigDecimalValue();
  176               if (v.compareTo(m) > 0)
  177               {
  178                   context.invalid(XmlErrorCodes.DATATYPE_MAX_INCLUSIVE_VALID,
  179                       new Object[] { "decimal", v, m, QNameHelper.readable(sType) });
  180                   return;
  181               }
  182           }
  183   
  184           // max ex
  185           XmlObject maxe = sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
  186           if (maxe != null)
  187           {
  188               BigDecimal m = ((XmlObjectBase)maxe).bigDecimalValue();
  189               if (v.compareTo(m) >= 0)
  190               {
  191                   context.invalid(XmlErrorCodes.DATATYPE_MAX_EXCLUSIVE_VALID,
  192                       new Object[] { "decimal", v, m, QNameHelper.readable(sType) });
  193                   return;
  194               }
  195           }
  196   
  197           // enumeration
  198           XmlObject[] vals = sType.getEnumerationValues();
  199           if (vals != null)
  200           {
  201               for (int i = 0; i < vals.length; i++)
  202                   if (v.equals(((XmlObjectBase)vals[i]).bigDecimalValue()))
  203                       return;
  204               context.invalid(XmlErrorCodes.DATATYPE_ENUM_VALID,
  205                   new Object[] { "decimal", v, QNameHelper.readable(sType) });
  206           }
  207       }
  208       
  209       protected void validate_simpleval(String lexical, ValidationContext ctx)
  210       {
  211           validateLexical(lexical, schemaType(), ctx);
  212           validateValue(bigDecimalValue(), schemaType(), ctx);
  213       }
  214   
  215   }

Save This Page
Home » xmlbeans-2.4.0-src » org.apache.xmlbeans.impl.values » [javadoc | source]