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   *    https://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.i18n.I18n;
24  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
25  import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
26  import org.apache.directory.api.util.Strings;
27  
28  
29  /**
30   * A SyntaxChecker which verifies that a value is a BootParameter according to 
31   * RFC 2307 :
32   * <pre>
33   * bootparameter     = key "=" server ":" path
34   *      key               = keystring
35   *      server            = keystring
36   *      path              = keystring
37   * </pre>
38   * 
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   */
41  @SuppressWarnings("serial")
42  public final class BootParameterSyntaxChecker extends SyntaxChecker
43  {
44      /**
45       * A static instance of BootParameterSyntaxChecker
46       */
47      public static final BootParameterSyntaxChecker INSTANCE = 
48          new BootParameterSyntaxChecker( SchemaConstants.BOOT_PARAMETER_SYNTAX );
49      
50      /**
51       * A static Builder for this class
52       */
53      public static final class Builder extends SCBuilder<BootParameterSyntaxChecker>
54      {
55          /**
56           * The Builder constructor
57           */
58          private Builder()
59          {
60              super( SchemaConstants.BOOT_PARAMETER_SYNTAX );
61          }
62          
63          
64          /**
65           * Create a new instance of BootParameterSyntaxChecker
66           * @return A new instance of BootParameterSyntaxChecker
67           */
68          @Override
69          public BootParameterSyntaxChecker build()
70          {
71              return new BootParameterSyntaxChecker( oid );
72          }
73      }
74  
75      
76      /**
77       * Creates a new instance of BootParameterSyntaxChecker.
78       * 
79       * @param oid The OID to use for this SyntaxChecker
80       */
81      private BootParameterSyntaxChecker( String oid )
82      {
83          super( oid );
84      }
85  
86      
87      /**
88       * @return An instance of the Builder for this class
89       */
90      public static Builder builder()
91      {
92          return new Builder();
93      }
94      
95      
96      private int parseKeyString( String strValue, int pos, char limit )
97      {
98          try 
99          { 
100             char c = strValue.charAt( pos );
101             
102             // The end of the keyString
103             if ( c == limit )
104             {
105                 return pos;
106             }
107             
108             // We must have a first alphabetic char
109             if ( Character.isUpperCase( c ) || Character.isLowerCase( c ) )
110             {
111                 pos++;
112             }
113             else
114             {
115                 return -1;
116             }
117             
118             c = strValue.charAt( pos );
119             
120             while ( c != limit )
121             {
122                 if ( Character.isUpperCase( c ) || Character.isLowerCase( c ) || Character.isDigit( c )
123                     || ( c == '-' ) || ( c == ';' ) || ( c == '_' ) )
124                 {
125                     pos++;
126                 }
127                 else
128                 {
129                     return -1;
130                 }
131 
132                 c = strValue.charAt( pos );
133             }
134             
135             return pos;
136         }
137         catch ( IndexOutOfBoundsException ioobe )
138         {
139             return -1;
140         }
141     }
142     
143     
144     private int parseKeyString( String strValue, int pos )
145     {
146         try 
147         { 
148             char c = strValue.charAt( pos );
149             
150             // We must have a first alphabetic char
151             if ( Character.isUpperCase( c ) || Character.isLowerCase( c ) )
152             {
153                 pos++;
154             }
155             else
156             {
157                 return -1;
158             }
159             
160             while ( pos < strValue.length() )
161             {
162                 c = strValue.charAt( pos );
163 
164                 if ( Character.isUpperCase( c ) || Character.isLowerCase( c ) || Character.isDigit( c )
165                     || ( c == '-' ) || ( c == ';' ) || ( c == '_' ) )
166                 {
167                     pos++;
168                 }
169                 else
170                 {
171                     return -1;
172                 }
173             }
174             
175             return pos;
176         }
177         catch ( IndexOutOfBoundsException ioobe )
178         {
179             return -1;
180         }
181     }
182     
183 
184     /**
185      * {@inheritDoc}
186      */
187     @Override
188     public boolean isValidSyntax( Object value )
189     {
190         String strValue;
191 
192         if ( value == null )
193         {
194             if ( LOG.isDebugEnabled() )
195             {
196                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, "null" ) );
197             }
198             
199             return false;
200         }
201 
202         if ( value instanceof String )
203         {
204             strValue = ( String ) value;
205         }
206         else if ( value instanceof byte[] )
207         {
208             strValue = Strings.utf8ToString( ( byte[] ) value );
209         }
210         else
211         {
212             strValue = value.toString();
213         }
214 
215         // The  BootParameter must at least contain a '=' and a ':', plus 3 keyStrings
216         if ( strValue.length() < 5 )
217         {
218             if ( LOG.isDebugEnabled() )
219             {
220                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
221             }
222             
223             return false;
224         }
225 
226         // The key
227         int pos = parseKeyString( strValue, 0, '=' );
228         
229         if ( pos == -1 )
230         {
231             if ( LOG.isDebugEnabled() )
232             {
233                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
234             }
235             
236             return false;
237         }
238         
239         if ( strValue.charAt( pos ) != '=' )
240         {
241             if ( LOG.isDebugEnabled() )
242             {
243                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
244             }
245             
246             return false;
247         }
248         else
249         {
250             pos++;
251         }
252 
253         // The server
254         pos = parseKeyString( strValue, pos, ':' );
255         
256         if ( pos == -1 )
257         {
258             if ( LOG.isDebugEnabled() )
259             {
260                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
261             }
262             
263             return false;
264         }
265         
266         if ( strValue.charAt( pos ) != ':' )
267         {
268             if ( LOG.isDebugEnabled() )
269             {
270                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
271             }
272             
273             return false;
274         }
275         else
276         {
277             pos++;
278         }
279 
280         // The path
281         pos = parseKeyString( strValue, pos );
282         
283         if ( pos == -1 )
284         {
285             if ( LOG.isDebugEnabled() )
286             {
287                 LOG.debug( I18n.err( I18n.ERR_13210_SYNTAX_INVALID, value ) );
288             }
289             
290             return false;
291         }
292         
293         return true;
294     }
295 }