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    
023    import org.apache.directory.shared.asn1.primitives.OID;
024    import org.apache.directory.shared.ldap.constants.SchemaConstants;
025    import org.apache.directory.shared.ldap.schema.SyntaxChecker;
026    import org.apache.directory.shared.ldap.util.StringTools;
027    import org.slf4j.Logger;
028    import org.slf4j.LoggerFactory;
029    
030    
031    /**
032     * A SyntaxChecker which verifies that a value is an oid according to RFC 4512.
033     * 
034     * From RFC 4512 :
035     * 
036     * oid = descr | numericoid
037     * descr = keystring
038     * keystring = leadkeychar *keychar
039     * leadkeychar = ALPHA
040     * keychar = ALPHA | DIGIT | HYPHEN
041     * number  = DIGIT | ( LDIGIT 1*DIGIT )
042     * ALPHA   = %x41-5A | %x61-7A              ; "A"-"Z" | "a"-"z"
043     * DIGIT   = %x30 | LDIGIT                  ; "0"-"9"
044     * LDIGIT  = %x31-39                        ; "1"-"9"
045     * HYPHEN  = %x2D                           ; hyphen ("-")
046     * numericoid = number 1*( DOT number )
047     * DOT     = %x2E                           ; period (".")
048     * 
049     *
050     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051     * @version $Rev$
052     */
053    public class OidSyntaxChecker extends SyntaxChecker
054    {
055        /** A logger for this class */
056        private static final Logger LOG = LoggerFactory.getLogger( OidSyntaxChecker.class );
057    
058        /** The serialVersionUID */
059        private static final long serialVersionUID = 1L;
060    
061        /**
062         * Creates a new instance of OidSyntaxChecker.
063         */
064        public OidSyntaxChecker()
065        {
066            super( SchemaConstants.OID_SYNTAX );
067        }
068    
069        
070        /**
071         * {@inheritDoc}
072         */
073        public boolean isValidSyntax( Object value )
074        {
075            String strValue = null;
076    
077            if ( value == null )
078            {
079                LOG.debug( "Syntax invalid for '{}'", value );
080                return false;
081            }
082            
083            if ( value instanceof String )
084            {
085                strValue = ( String ) value;
086            }
087            else if ( value instanceof byte[] )
088            {
089                strValue = StringTools.utf8ToString( ( byte[] ) value ); 
090            }
091            else
092            {
093                strValue = value.toString();
094            }
095    
096            if ( strValue.length() == 0 )
097            {
098                LOG.debug( "Syntax invalid for '{}'", value );
099                return false;
100            }
101            
102            // if the first character is a digit it's an attempt at an OID and must be
103            // checked to make sure there are no other chars except '.' and digits.
104            if ( StringTools.isDigit( strValue.charAt( 0 ) ) )
105            {
106                if ( ! OID.isOID( strValue ) )
107                {
108                    LOG.debug( "Syntax invalid for '{}'", value );
109                    return false;
110                }
111                else
112                {
113                    LOG.debug( "Syntax valid for '{}'", value );
114                    return true;
115                }
116            }
117    
118            // here we just need to make sure that we have the right characters in the 
119            // string and that it starts with a letter.
120            if ( StringTools.isAlphaASCII( strValue, 0 ) )
121            {
122                for ( int index = 0; index < strValue.length(); index++ )
123                {
124                    if ( ! StringTools.isAlphaDigitMinus( strValue, index ))
125                    {
126                        LOG.debug( "Syntax invalid for '{}'", value );
127                        return false;
128                    }
129                }
130                
131                LOG.debug( "Syntax valid for '{}'", value );
132                return true;
133            }
134            else
135            {
136                LOG.debug( "Syntax invalid for '{}'", value );
137                return false;
138            }
139        }
140    }