View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.model.schema.syntaxCheckers;
21  
22  
23  import org.apache.directory.api.asn1.util.Oid;
24  import org.apache.directory.api.i18n.I18n;
25  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
26  import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
27  import org.apache.directory.api.util.Chars;
28  import org.apache.directory.api.util.Strings;
29  
30  
31  /**
32   * A SyntaxChecker which verifies that a value is an oid according to RFC 4512.
33   * <p>
34   * From RFC 4512 :
35   * <pre>
36   * oid = descr | numericoid
37   * descr = keystring
38   * keystring = leadkeychar *keychar
39   * leadkeychar = ALPHA
40   * keychar = ALPHA | DIGIT | HYPHEN
41   * number  = DIGIT | ( LDIGIT 1*DIGIT )
42   * ALPHA   = %x41-5A | %x61-7A              ; "A"-"Z" | "a"-"z"
43   * DIGIT   = %x30 | LDIGIT                  ; "0"-"9"
44   * LDIGIT  = %x31-39                        ; "1"-"9"
45   * HYPHEN  = %x2D                           ; hyphen ("-")
46   * numericoid = number 1*( DOT number )
47   * DOT     = %x2E                           ; period (".")
48   * </pre>
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   */
52  @SuppressWarnings("serial")
53  public final class OidSyntaxChecker extends SyntaxChecker
54  {
55      /**
56       * A static instance of OidSyntaxChecker
57       */
58      public static final OidSyntaxChecker INSTANCE = new OidSyntaxChecker( SchemaConstants.OID_SYNTAX );
59      
60      /**
61       * A static Builder for this class
62       */
63      public static final class Builder extends SCBuilder<OidSyntaxChecker>
64      {
65          /**
66           * The Builder constructor
67           */
68          private Builder()
69          {
70              super( SchemaConstants.OID_SYNTAX );
71          }
72          
73          
74          /**
75           * Create a new instance of OidSyntaxChecker
76           * @return A new instance of OidSyntaxChecker
77           */
78          @Override
79          public OidSyntaxChecker build()
80          {
81              return new OidSyntaxChecker( oid );
82          }
83      }
84  
85      
86      /**
87       * Creates a new instance of OidSyntaxChecker.
88       * 
89       * @param oid The OID to use for this SyntaxChecker
90       */
91      private OidSyntaxChecker( String oid )
92      {
93          super( oid );
94      }
95  
96      
97      /**
98       * @return An instance of the Builder for this class
99       */
100     public static Builder builder()
101     {
102         return new Builder();
103     }
104 
105 
106     /**
107      * {@inheritDoc}
108      */
109     @Override
110     public boolean isValidSyntax( Object value )
111     {
112         String strValue;
113 
114         if ( value == null )
115         {
116             if ( LOG.isDebugEnabled() )
117             {
118                 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, "null" ) );
119             }
120             
121             return false;
122         }
123 
124         if ( value instanceof String )
125         {
126             strValue = ( String ) value;
127         }
128         else if ( value instanceof byte[] )
129         {
130             strValue = Strings.utf8ToString( ( byte[] ) value );
131         }
132         else
133         {
134             strValue = value.toString();
135         }
136 
137         if ( strValue.length() == 0 )
138         {
139             if ( LOG.isDebugEnabled() )
140             {
141                 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) );
142             }
143             
144             return false;
145         }
146 
147         // if the first character is a digit it's an attempt at an OID and must be
148         // checked to make sure there are no other chars except '.' and digits.
149         if ( Chars.isDigit( strValue.charAt( 0 ) ) )
150         {
151             boolean result = Oid.isOid(  strValue  );
152             
153             if ( LOG.isDebugEnabled() )
154             {
155                 if ( result )
156                 {
157                     LOG.debug( I18n.msg( I18n.MSG_04489_SYNTAX_VALID, value ) );
158                 }
159                 else
160                 {
161                     LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) );
162                 }
163             }
164             
165             return result;
166         }
167 
168         // here we just need to make sure that we have the right characters in the 
169         // string and that it starts with a letter.
170         if ( Chars.isAlphaASCII( strValue, 0 ) )
171         {
172             for ( int index = 0; index < strValue.length(); index++ )
173             {
174                 char c = strValue.charAt( index );
175                 
176                 if ( !Chars.isAlphaDigitMinus( c ) )
177                 {
178                     if ( LOG.isDebugEnabled() )
179                     {
180                         LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) );
181                     }
182                     
183                     return false;
184                 }
185             }
186 
187             if ( LOG.isDebugEnabled() )
188             {
189                 LOG.debug( I18n.msg( I18n.MSG_04489_SYNTAX_VALID, value ) );
190             }
191             
192             return true;
193         }
194         else
195         {
196             if ( LOG.isDebugEnabled() )
197             {
198                 LOG.debug( I18n.err( I18n.ERR_04488_SYNTAX_INVALID, value ) );
199             }
200             
201             return false;
202         }
203     }
204 }