001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.ldap.schema.syntaxCheckers;
021    
022    import org.apache.directory.shared.ldap.constants.SchemaConstants;
023    import org.apache.directory.shared.ldap.schema.SyntaxChecker;
024    import org.apache.directory.shared.ldap.util.StringTools;
025    import org.slf4j.Logger;
026    import org.slf4j.LoggerFactory;
027    
028    
029    /**
030     * A SyntaxChecker which verifies that a value is a valid Java primitive int or
031     * the Integer wrapper.  Essentially this constrains the min and max values of
032     * the Integer.
033     *
034     * From RFC 4517 :
035     *
036     * Integer = ( HYPHEN LDIGIT *DIGIT ) | number
037     *
038     * From RFC 4512 :
039     * number  = DIGIT | ( LDIGIT 1*DIGIT )
040     * DIGIT   = %x30 | LDIGIT       ; "0"-"9"
041     * LDIGIT  = %x31-39             ; "1"-"9"
042     * HYPHEN  = %x2D                ; hyphen ("-")
043     *
044     *
045     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
046     * @version $Rev$
047     */
048    public class JavaIntegerSyntaxChecker extends SyntaxChecker
049    {
050        /** A logger for this class */
051        private static final Logger LOG = LoggerFactory.getLogger( JavaIntegerSyntaxChecker.class );
052    
053        /** The serialVersionUID */
054        private static final long serialVersionUID = 1L;
055    
056        /**
057         * Creates a new instance of JavaIntegerSyntaxChecker.
058         */
059        public JavaIntegerSyntaxChecker()
060        {
061            super( SchemaConstants.JAVA_INT_SYNTAX );
062        }
063    
064    
065        /**
066         * {@inheritDoc}
067         */
068        public boolean isValidSyntax( Object value )
069        {
070            String strValue =null;
071    
072            if ( value == null )
073            {
074                LOG.debug( "Syntax invalid for '{}'", value );
075                return false;
076            }
077    
078            if ( value instanceof String )
079            {
080                strValue = ( String ) value;
081            }
082            else if ( value instanceof byte[] )
083            {
084                strValue = StringTools.utf8ToString( ( byte[] ) value );
085            }
086            else
087            {
088                strValue = value.toString();
089            }
090    
091            if ( strValue.length() == 0 )
092            {
093                LOG.debug( "Syntax invalid for '{}'", value );
094                return false;
095            }
096    
097            // The first char must be either a '-' or in [0..9].
098            // If it's a '0', then there should be any other char after
099            int pos = 0;
100            char c = strValue.charAt( pos );
101    
102            if ( c == '-' )
103            {
104                pos = 1;
105            }
106            else if ( !StringTools.isDigit( c ) )
107            {
108                LOG.debug( "Syntax invalid for '{}'", value );
109                return false;
110            }
111            else if ( c == '0' )
112            {
113                boolean result = strValue.length() <= 1;
114                
115                if ( result )
116                {
117                    LOG.debug( "Syntax valid for '{}'", value );
118                }
119                else
120                {
121                    LOG.debug( "Syntax invalid for '{}'", value );
122                }
123                
124                return result;
125            }
126    
127            // We must have at least a digit which is not '0'
128            if ( !StringTools.isDigit( strValue, pos ) )
129            {
130                LOG.debug( "Syntax invalid for '{}'", value );
131                return false;
132            }
133            else if ( StringTools.isCharASCII( strValue, pos, '0' ) )
134            {
135                LOG.debug( "Syntax invalid for '{}'", value );
136                return false;
137            }
138            else
139            {
140                pos++;
141            }
142    
143            while ( StringTools.isDigit( strValue, pos) )
144            {
145                pos++;
146            }
147    
148            if ( pos != strValue.length() )
149            {
150                LOG.debug( "Syntax invalid for '{}'", value );
151                return false;
152            }
153    
154            try
155            {
156                Integer.valueOf( strValue );
157                LOG.debug( "Syntax valid for '{}'", value );
158                return true;
159            }
160            catch ( NumberFormatException e )
161            {
162                LOG.debug( "Syntax invalid for '{}'", value );
163                return false;
164            }
165        }
166    }