Package org.apache.xerces.validators.datatype

Source Code of org.apache.xerces.validators.datatype.TimeDurationDatatypeValidator

/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999, 2000 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
*    nor may "Apache" appear in their name, without prior written
*    permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.apache.org.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

package org.apache.xerces.validators.datatype;

import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.text.ParseException;
import org.apache.xerces.utils.regex.RegularExpression;
import org.apache.xerces.validators.schema.SchemaSymbols;

/**
*
* TimeDurationValidator validates that XML content is a W3C timeDuration.
*
* @author Ted Leung, George Joseph
* @version $Id: TimeDurationDatatypeValidator.java,v 1.5 2000/08/01 06:06:24 jeffreyr Exp $
*/

public class TimeDurationDatatypeValidator extends AbstractDatatypeValidator {

   private Locale            fLocale           = null;
   private DatatypeValidator fBaseValidator    = null; // A Native datatype is null
   private String            fPattern          = null;
   private long              fMaxInclusive     = 0L;
   private long              fMaxExclusive     = 0L;
   private long              fMinInclusive     = 0L;
   private long              fMinExclusive     = 0L;
   private long              fDuration         = 0L;
   private long              fPeriod           = 0L;


   private boolean           isMaxExclusiveDefined = false;
   private boolean           isMaxInclusiveDefined = false;
   private boolean           isMinExclusiveDefined = false;
   private boolean           isMinInclusiveDefined = false;

   private int               fFacetsDefined        = 0;

   private boolean           fDerivedByList        = false;


   private long[]            fEnumTimeDuration = null; // Time duration is represented internally as longs

   private DatatypeMessageProvider fMessageProvider = new DatatypeMessageProvider();


    public  TimeDurationDatatypeValidator () throws InvalidDatatypeFacetException {
        this( null, null, false ); // Native, No Facets defined, Restriction
    }

    public  TimeDurationDatatypeValidator ( DatatypeValidator base, Hashtable facets,
                  boolean derivedByList ) throws InvalidDatatypeFacetException {
        if ( base != null )
            setBasetype( base ); // Set base type


        fDerivedByList = derivedByList;
        // Set Facets if any defined

        if ( facets != null  )  {
            if ( fDerivedByList == false ) { // Restriction
                if (fBaseValidator != null)
                    //if (!fBaseValidator.ensureFacetsAreConsistent(facets))
                      //  throw new InvalidDatatypeFacetException(
                        //                                       getErrorString( DatatypeMessageProvider.FacetsInconsistent,
                          //                                                     DatatypeMessageProvider.MSG_NONE, null));

                for (Enumeration e = facets.keys(); e.hasMoreElements();) {

                    String key = (String) e.nextElement();

                    if (key.equals(SchemaSymbols.ELT_PATTERN)) {
                        fFacetsDefined += DatatypeValidator.FACET_PATTERN;
                        fPattern = (String)facets.get(key);
                    } else if (key.equals(SchemaSymbols.ELT_ENUMERATION)) {
                        fFacetsDefined += DatatypeValidator.FACET_ENUMERATION;
                        continue; //Treat the enumeration after this for loop
                    } else if (key.equals(SchemaSymbols.ELT_MAXINCLUSIVE)) {
                        fFacetsDefined += DatatypeValidator.FACET_MAXINCLUSIVE;
                        String value = null;
                        try {
                            value         = ((String)facets.get(key));
                            fMaxInclusive = normalizeDuration( value.toCharArray(), 0 );
                        } catch ( InvalidDatatypeValueException nfe ){
                            throw new InvalidDatatypeFacetException( getErrorString(
                                                                                   DatatypeMessageProvider.IllegalFacetValue,
                                                                                   DatatypeMessageProvider.MSG_NONE,
                                                                                   new Object [] { value, key}));
                        }
                    } else if (key.equals(SchemaSymbols.ELT_MAXEXCLUSIVE)) {
                        fFacetsDefined += DatatypeValidator.FACET_MAXEXCLUSIVE;
                        String value = null;
                        try {
                            value         = ((String)facets.get(key));
                            fMaxExclusive = normalizeDuration( value.toCharArray(), 0 );
                        } catch ( InvalidDatatypeValueException nfe ){
                            throw new InvalidDatatypeFacetException( getErrorString(
                                                                                   DatatypeMessageProvider.IllegalFacetValue,
                                                                                   DatatypeMessageProvider.MSG_NONE,
                                                                                   new Object [] { value, key}));
                        }
                    } else if (key.equals(SchemaSymbols.ELT_MININCLUSIVE)) {
                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
                        String value = null;
                        try {
                            value         = ((String)facets.get(key));
                            fMinInclusive = normalizeDuration( value.toCharArray(), 0 );
                        } catch ( InvalidDatatypeValueException nfe ){
                            throw new InvalidDatatypeFacetException( getErrorString(
                                                                                   DatatypeMessageProvider.IllegalFacetValue,
                                                                                   DatatypeMessageProvider.MSG_NONE,
                                                                                   new Object [] { value, key}));
                        }
                    } else if (key.equals(SchemaSymbols.ELT_MINEXCLUSIVE)) {
                        fFacetsDefined += DatatypeValidator.FACET_MININCLUSIVE;
                        String value = null;
                        try {
                            value         = ((String)facets.get(key));
                            fMinExclusive = normalizeDuration( value.toCharArray(), 0 );

                        } catch ( InvalidDatatypeValueException nfe ) {
                            throw new InvalidDatatypeFacetException( getErrorString(
                                                                                   DatatypeMessageProvider.IllegalFacetValue,
                                                                                   DatatypeMessageProvider.MSG_NONE,
                                                                                   new Object [] { value, key}));
                        }
                    } else {
                        throw new InvalidDatatypeFacetException( getErrorStringDatatypeMessageProvider.MSG_FORMAT_FAILURE,
                                                                                  DatatypeMessageProvider.MSG_NONE,
                                                                                  null));
                    }
                }

                isMaxExclusiveDefined = ((fFacetsDefined &
                                          DatatypeValidator.FACET_MAXEXCLUSIVE ) != 0 )?true:false;
                isMaxInclusiveDefined = ((fFacetsDefined &
                                          DatatypeValidator.FACET_MAXINCLUSIVE ) != 0 )?true:false;
                isMinExclusiveDefined = ((fFacetsDefined &
                                          DatatypeValidator.FACET_MINEXCLUSIVE ) != 0 )?true:false;
                isMinInclusiveDefined = ((fFacetsDefined &
                                          DatatypeValidator.FACET_MININCLUSIVE ) != 0 )?true:false;


                if ( isMaxExclusiveDefined && isMaxInclusiveDefined ) {
                    throw new InvalidDatatypeFacetException(
                                                "It is an error for both maxInclusive and maxExclusive to be specified for the same datatype." );
                }
                if ( isMinExclusiveDefined && isMinInclusiveDefined ) {
                    throw new InvalidDatatypeFacetException(
                                                "It is an error for both minInclusive and minExclusive to be specified for the same datatype." );
                }


                if ( (fFacetsDefined & DatatypeValidator.FACET_ENUMERATION ) != 0 ) {
                    Vector v = (Vector) facets.get(SchemaSymbols.ELT_ENUMERATION);   
                    if (v != null) {
                        fEnumTimeDuration = new long[v.size()];
                        int     i     = 0;
                        String  value = null;
                        try {
                            for (; i < v.size(); i++){
                                value = (String)v.elementAt(i);
                                fEnumTimeDuration[i] =
                                normalizeDuration( value.toCharArray(),0 );
                                boundsCheck(fEnumTimeDuration[i]); // Check against max,min Inclusive, Exclusives
                            }
                        } catch (InvalidDatatypeValueException idve) {
                            throw new InvalidDatatypeFacetException(
                                                                   getErrorString(DatatypeMessageProvider.InvalidEnumValue,
                                                                                  DatatypeMessageProvider.MSG_NONE,
                                                                                  new Object [] { v.elementAt(i)}));
                        }
                    }
                }
            } else { //Derived by List TODO

            }
        }// End Facet definition
    }


    /**
     * validates a String to be a Lexical representation
     * of a TimeDuration Datatype.
     *
     * @param content A string containing the content to be validated
     * @param state
     * @return
     * @exception InvalidDatatypeValueException
     *                   If String is does not represent a
     *                   valid TimeDuration datatype.
     */
    public Object validate(String content, Object state)
                                       throws InvalidDatatypeValueException{
        long normalizedValue;

        if ( fDerivedByList == false  ) { //derived by constraint
             if ( fPattern != null ) {
                 RegularExpression regex = new RegularExpression(fPattern, "X" );
                 if ( regex.matches( content) == false )
                     throw new InvalidDatatypeValueException("Value'"+content+
                                  "does not match regular expression facet" + fPattern );
             }

             normalizedValue = normalizeDuration(content.toCharArray(), 0 );
             try {
                 boundsCheck( normalizedValue );
             } catch( InvalidDatatypeFacetException ex ){
                 throw new InvalidDatatypeValueException( "Boundary Exception" );
             }

             if( fEnumTimeDuration != null )
                 enumCheck( normalizedValue );

        } else { //derived by list
        }
        return null;
    }


    /**
     * set the base type for this datatype
     *
     * @param base the validator for this type's base type
     *
     */
    public void setBasetype(DatatypeValidator base) {
        fBaseValidator = base;
    }


    /**
    * set the locate to be used for error messages
    */
    public void setLocale(Locale locale) {
    }


    public int compare( String content1, String content2) {
        return -1;
    }

    public Hashtable getFacets(){
        return null;
    }

    public static long normalizeDuration(char[] value, int start )
    throws InvalidDatatypeValueException
    {
        int i=0, j=0, k=0, l=0, m=0;
        int sepindex  = 0;
        int index     = start;
        int lindex    = 0;
        int endindex  = (start+ value.length)-1;
        int pendindex = endindex;

        final char[] dseps = {'Y','M','D'};
        final char[] tseps = {'H','M','S'};
        final char[] msc = {'0','0','0'};

        final int[] buckets = new int[Calendar.FIELD_COUNT];
        for (i=0;i<buckets.length;i++)
            buckets[i]=0;

        boolean intime           = false;
        boolean fixed            = false;
        boolean p1negative       = false;
        boolean p2negative       = false;
        boolean p1specified      = false;
        boolean p2specified      = false;
        GregorianCalendar cstart = null;
        GregorianCalendar cend   = null;

        //Start phase 1: capture start and/or end instant.
        try
        {
            if (value[index]=='-')
            {
                p1negative=true;
            }
            //Look for the forward slash.
            int ix = indexOf(value, start, '/');

            if (ix > -1 && ix < endindex)
            {
                if (value[ix+1]=='-')
                {
                    p2negative=true;
                }
                //If the first term starts with a 'P', pin it for later parsing
                if (value[(p1negative?index+1:index)]=='P')
                {
                    if (p1negative)
                        index++;
                    p1specified = true;
                    pendindex   = ix-1;
                }
                //Otherwise parse it for a timeInstant
                else
                {
                    cstart = (GregorianCalendar) normalizeInstant(value, index, ix-index);
                }
                //If the second term starts with a 'P', pin it for later parsing
                if (value[(p2negative?(ix+2):(ix+1))]=='P')
                {
                    p2specified=true;
                    index=(p2negative?(ix+2):(ix+1));
                }
                //Otherwise parse it for a timeInstant
                else
                {
                    ix++;
                    cend = (GregorianCalendarnormalizeInstant(value,ix,(endindex-ix)+1);
                }
            }
            //Only one term specified.
            else
            {
                index=(p1negative?(start+1):(start));
            }
            //If both terms are instants, return the millisecond difference
            if (cstart != null && cend != null)
            {
                return((cend.getTime().getTime() - cstart.getTime().getTime()));
            }
            //If both terms are 'P', error.
            if (p1specified && p2specified)
                throw new ParseException("Period cannot be expressed as 2 durations.", 0);

            if (p1specified && value[index] != 'P')
            {
                throw new ParseException("Invalid start character for timeDuration:"+value[index], index);
            }
            if (p2specified && value[index] != 'P')
            {
                throw new ParseException("Invalid start character for timeDuration:"+value[index], index);
            }
        } catch (Exception e)
        {
            throw new InvalidDatatypeValueException(e.toString());
        }
        //Second phase....parse 'P' term
        try
        {

            lindex=index+1;
            for (i=index+1;i<=pendindex;i++)
            {
                //Accumulate digits.
                if (Character.isDigit(value[i]) || value[i]=='.')
                {
                    if (value[i]=='.')fixed=true;
                    continue;
                }
                if (value[i]=='T')
                {
                    intime=true;
                    sepindex=0;
                    lindex=i+1;
                    continue;
                }
                //If you get a separator, it must be appropriate for the section.
                sepindex = indexOf((intime?tseps:dseps), sepindex, value[i]);
                if (sepindex == -1)
                    throw new ParseException("Illegal or misplaced separator.", i);
                sepindex++;
                //Fractional digits are allowed only for seconds.
                if (fixed && value[i]!='S')
                    throw new ParseException("Fractional digits allowed only for 'seconds'.", i);

                j=0;
                switch (value[i])
                {
                case('Y'):
                    {
                        if (intime)throw new ParseException("Year must be specified before 'T' separator.", i);
                        buckets[Calendar.YEAR]= parseInt(value, lindex, i-lindex);
                        break;
                    }
                case('D'):
                    {
                        if (intime)throw new ParseException("Days must be specified before 'T' separator.", i);
                        buckets[Calendar.DAY_OF_MONTH]= parseInt(value, lindex, i-lindex);
                        break;
                    }
                case('H'):
                    {
                        if (!intime)throw new ParseException("Hours must be specified after 'T' separator.", i);
                        buckets[Calendar.HOUR_OF_DAY]= parseInt(value, lindex, i-lindex);
                        break;
                    }
                case('M'):
                    {
                        buckets[(intime?Calendar.MINUTE:Calendar.MONTH)]= parseInt(value, lindex, i-lindex);
                        break;
                    }
                case('S'):
                    {
                        if (!intime)throw new ParseException("Seconds must be specified after 'T' separator.", i);
                        if (!fixed)buckets[Calendar.SECOND]= parseInt(value, lindex, i-lindex);
                        else
                        {
                            int ps = indexOf(value, lindex, '.');
                            buckets[Calendar.SECOND]= parseInt(value, lindex, ps-lindex);
                            ps++;k=0;
                            while ((ps <= pendindex) && (k<3) && Character.isDigit(value[ps]))
                                msc[k++]=value[ps++];
                            buckets[Calendar.MILLISECOND]= parseInt(msc, 0, 3);
                            fixed=false;
                        }
                        break;
                    }
                default:
                    {
                        throw new ParseException("Illegal 'picture' character: "+value[i], i);
                    }
                }
                lindex=i+1;
            }
        } catch (Exception e)
        {
            throw new InvalidDatatypeValueException(e.toString());
        }
        //Third phase, make the calculations.
        try
        {
            //Roll the start calendar forward and return difference.
            if (cstart !=null)
            {
                long st = cstart.getTime().getTime();
                for (k=0;k<buckets.length;k++)
                    if (buckets[k]!=0)cstart.add(k, (p2negative?-buckets[k]:buckets[k]));
                long ms = cstart.getTime().getTime();
                return((ms-st));
            }
            //Roll the end calendar backward and return difference.
            if (cend !=null)
            {
                long st = cend.getTime().getTime();
                for (k=0;k<buckets.length;k++)
                    if (buckets[k]>0) cend.add(k, (p1negative?buckets[k]:-buckets[k]));
                long ms = cend.getTime().getTime();
                return((ms-st));
            }
            //Otherwise roll the relative specification forward and reverse the sing as appropriate. 
            long r=(((long)(( (buckets[Calendar.YEAR]*31104000L)+
                              (buckets[Calendar.MONTH]*2592000L)+
                              (buckets[Calendar.DAY_OF_MONTH]*86400L)+
                              (buckets[Calendar.HOUR_OF_DAY]*3600L)+
                              (buckets[Calendar.MINUTE]*60L)+
                              (buckets[Calendar.SECOND]))*1000L)+
                     (buckets[Calendar.MILLISECOND])));

            return((p1negative?-r:r));
        } catch (Exception e)
        {
            throw new InvalidDatatypeValueException(e.toString());
        }
    }

    public static Calendar normalizeInstant(char[] value, int start,
                                 int length) throws InvalidDatatypeValueException
    {
        boolean negative=false;
        boolean tznegative=false;
        int     tzoffset=0;
        int     tzhh=0,tzmm=0;
        int     i=start,j=0,k=0,l=0,m=0;
        final char[]ms={'0','0','0'};
        final   Calendar cal = new GregorianCalendar();
        final   int endindex = (start+length)-1;

        try
        {
            if (length < 16) throw new ParseException("Value is too short.",0);
            cal.clear();
            cal.setLenient(false);
//  If there's a leading sign, set the appropriate Era.
            if (value[i]=='-'||value[i]=='+')
            {
                cal.set(Calendar.ERA, (value[i]=='-'?GregorianCalendar.BC:GregorianCalendar.AD));
                i++;
            }
//  Grab the year (might be > 9999), month, day, hour and minute fields   
            j=indexOf(value,i,'-',i+5);
            if (j==-1 || j>endindex)throw new ParseException("Year separator is missing or misplaced.", i);
            cal.set(Calendar.YEAR, parseInt(value,i,j-i));
            i=j+1;
            cal.set(Calendar.MONTH, parseInt(value,i,2)-1);
            i+=2;
            if (value[i]!='-')throw new ParseException("Month separator is missing or misplaced.",i);
            cal.set(Calendar.DAY_OF_MONTH, parseInt(value,i+1,2));
            i+=3;
            if (value[i]!='T')throw new ParseException("Time separator is missing or misplaced.",i);
            cal.set(Calendar.HOUR_OF_DAY, parseInt(value,i+1,2));
            i+=3;
            if (value[i]!=':')throw new ParseException("Hour separator is missing or misplaced.",i);
            cal.set(Calendar.MINUTE, parseInt(value,i+1,2));
            i+=3;
//  Seconds are optional
            if ((endindex-i)>1 && (value[i]==':'))
            {
                cal.set(Calendar.SECOND, parseInt(value,i+1,2));
                i+=3;
// Grab optional fractional seconds to 3 decimal places.
                if (i<endindex && value[i]=='.')
                {
                    i++;k=0;
                    while ((i <= endindex) && (k<3) && Character.isDigit(value[i]))
                        ms[k++]=value[i++];

                    cal.set(Calendar.MILLISECOND, parseInt(ms,0,3));
                }
//  Eat any remaining digits.
                while (i<=endindex && Character.isDigit(value[i]))  i++;
            }
//  Check for timezone.
            if (i<=endindex)
            {
                if (value[i]=='Z')
                {
                    cal.set(Calendar.ZONE_OFFSET, 0);
                }
//          else if ((endindex-i)==2 || (endindex-i)==5)
                else if (value[i]=='-' || value[i]=='+')
                {
                    tznegative = (value[i]=='-');
                    tzhh=parseInt(value,i+1,2);
                    if ((endindex-i)==5)
                    {
                        if (value[i+3] != ':')throw new ParseException("time zone must be 'hh:mm'.",i);
                        tzmm=parseInt(value,i+4,2);
                    }
                    tzoffset=((tzhh*3600000)+(tzmm*60000));
                    cal.set(Calendar.ZONE_OFFSET, (tznegative?-tzoffset:tzoffset));
                } else throw new ParseException("Unrecognized time zone.",i);
            }
            return(cal);
        } catch (Exception e)
        {
            e.printStackTrace();
            throw new InvalidDatatypeValueException("Unable to parse timeInstant "+e.toString());
        }
    }

  /**
     * Returns a copy of this object.
     */
    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("clone() is not supported in "+this.getClass().getName());
    }





    /*
     * check that a facet is in range, assumes that facets are compatible -- compatibility ensured by setFacets
     */
    private void boundsCheck(long f) throws InvalidDatatypeFacetException {
        boolean inUpperBound = false;
        boolean inLowerBound = false;

        if ( isMaxInclusiveDefined ) {
            inUpperBound = ( f <= fMaxInclusive );
        } else if ( isMaxExclusiveDefined ) {
            inUpperBound = ( f <  fMaxExclusive );
        }

        if ( isMinInclusiveDefined ) {
            inLowerBound = ( f >= fMinInclusive );
        } else if ( isMinExclusiveDefined ) {
            inLowerBound = ( f >  fMinExclusive );
        }

        if ( inUpperBound == false  || inLowerBound == false ) { // within bounds ?
            throw new InvalidDatatypeFacetException(
                                                   getErrorString(DatatypeMessageProvider.OutOfBounds,
                                                                  DatatypeMessageProvider.MSG_NONE,
                                                                  new Object [] { new Long(f),"","","",""}));//REVISIT
        }
    }

    private void enumCheck(long d) throws InvalidDatatypeValueException {
        for (int i = 0; i < this.fEnumTimeDuration.length; i++) {
            if (d == fEnumTimeDuration[i]) return;
        }
        throw new InvalidDatatypeValueException(
      getErrorString(DatatypeMessageProvider.NotAnEnumValue,
                    DatatypeMessageProvider.MSG_NONE,
                    new Object [] { new Long( d ) }));
    }




    private String getErrorString(int major, int minor, Object args[]) {
        try {
            return fMessageProvider.createMessage(fLocale, major, minor, args);
        } catch (Exception e) {
            return "Illegal Errorcode "+minor;
        }
    }


    private static final int indexOf(char[] value, int start, char s)
    {
        return(indexOf(value,start,s,value.length-1));
    }
    private static final int indexOf(char[] value, int start, char s, int max)
    {
        for (int i=start;i<=max;i++)if (value[i]==s) return(i);
        return(-1);
    }
    private static final int indexOneOf(char[] value, int start, String s)
    {
        return(indexOneOf(value,start,s,value.length-1));
    }
    private static final int indexOneOf(char[] value, int start, String s, int max)
    {
        for (int i=start;i<max;i++)
            for (int j=0;j<s.length();j++) if (value[i] == s.charAt(j))return(i);
        return(-1);
    }
//     parseInt is a copy of the Integer.parseInt method, modified to accept
// a character array.
    private static final int parseInt(char[] s, int start, int length)     throws NumberFormatException
    {
        if (s == null) throw new NumberFormatException("null");
        int radix=10;
        int result = 0;
        boolean negative = false;
        int i= start;
        int limit;
        int multmin;
        int digit=0;

        if (length <= 0) throw new NumberFormatException(new String(s,start,length));
        if (s[i] == '-')
        {
            negative = true;
            limit = Integer.MIN_VALUE;
            i++;
        } else if (s[i]=='+')
        {
            negative = false;
            limit = -Integer.MAX_VALUE;
            i++;
        } else
        {
            limit = -Integer.MAX_VALUE;
        }
        multmin = limit / radix;
        if (i < (start+length))
        {
            digit = Character.digit(s[i++],radix);
            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
            else result = -digit;
        }
        while (i < (start+length))
        {
            digit = Character.digit(s[i++],radix);
            if (digit < 0) throw new NumberFormatException(new String(s,start,length));
            if (result < multmin) throw new NumberFormatException(new String(s,start,length));
            result *= radix;
            if (result < limit + digit) throw new NumberFormatException(new String(s,start,length));
            result -= digit;
        }

        if (negative)
        {
            if (i > 1) return result;
            else throw new NumberFormatException(new String(s,start,length));
        }
        return -result;



    }

}

TOP

Related Classes of org.apache.xerces.validators.datatype.TimeDurationDatatypeValidator

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.