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 java.util.HashSet;
24  import java.util.Set;
25  
26  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
27  import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
28  import org.apache.directory.api.util.Chars;
29  import org.apache.directory.api.util.Strings;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  
34  /**
35   * A SyntaxChecker which verifies that a value is a delivery method 
36   * according to RFC 4517.
37   * 
38   * From RFC 4517 & RFC 4512:
39   * 
40   * DeliveryMethod = pdm *( WSP DOLLAR WSP pdm )
41   *
42   * pdm = "any" | "mhs" | "physical" | "telex" | "teletex" |
43   *       "g3fax" | "g4fax" | "ia5" | "videotex" | "telephone"
44   *           
45   * WSP     = 0*SPACE  ; zero or more " "
46   * DOLLAR  = %x24 ; dollar sign ("$")
47   * SPACE   = %x20 ; space (" ")
48   * 
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   */
52  @SuppressWarnings("serial")
53  public class DeliveryMethodSyntaxChecker extends SyntaxChecker
54  {
55      /** A logger for this class */
56      private static final Logger LOG = LoggerFactory.getLogger( DeliveryMethodSyntaxChecker.class );
57  
58      private static final String[] PDMS =
59          {
60              "any", "mhs", "physical", "telex", "teletex",
61              "g3fax", "g4fax", "ia5", "videotex", "telephone"
62      };
63  
64      /** The Set which contains the delivery methods */
65      private static final Set<String> DELIVERY_METHODS = new HashSet<String>();
66  
67      /** Initialization of the delivery methods set */
68      static
69      {
70          for ( String country : PDMS )
71          {
72              DELIVERY_METHODS.add( country );
73          }
74      }
75  
76  
77      /**
78       * 
79       * Creates a new instance of DeliveryMethodSyntaxChecker.
80       *
81       */
82      public DeliveryMethodSyntaxChecker()
83      {
84          super( SchemaConstants.DELIVERY_METHOD_SYNTAX );
85      }
86  
87  
88      /**
89       * 
90       * Check if the string contains a delivery method which has 
91       * not already been found.
92       * 
93       * @param strValue The string we want to look into for a PDM 
94       * @param pos The current position in the string
95       * @param pdms The set containing all the PDM
96       * @return if a Prefered Delivery Method is found in the given string, returns 
97       * its position, otherwise, returns -1
98       */
99      private int isPdm( String strValue, int start, Set<String> pdms )
100     {
101         int pos = start;
102 
103         while ( Chars.isAlphaDigit( strValue, pos ) )
104         {
105             pos++;
106         }
107 
108         // No ascii string, this is not a delivery method
109         if ( pos == start )
110         {
111             return -1;
112         }
113 
114         String pdm = strValue.substring( start, pos );
115 
116         if ( !DELIVERY_METHODS.contains( pdm ) )
117         {
118             // The delivery method is unknown
119             return -1;
120         }
121         else
122         {
123             if ( pdms.contains( pdm ) )
124             {
125                 // The delivery method has already been found
126                 return -1;
127             }
128             else
129             {
130                 pdms.add( pdm );
131                 return pos;
132             }
133         }
134     }
135 
136 
137     /**
138      * {@inheritDoc}
139      */
140     public boolean isValidSyntax( Object value )
141     {
142         String strValue = null;
143 
144         if ( value == null )
145         {
146             LOG.debug( "Syntax invalid for 'null'" );
147             return false;
148         }
149 
150         if ( value instanceof String )
151         {
152             strValue = ( String ) value;
153         }
154         else if ( value instanceof byte[] )
155         {
156             strValue = Strings.utf8ToString( ( byte[] ) value );
157         }
158         else
159         {
160             strValue = value.toString();
161         }
162 
163         if ( strValue.length() == 0 )
164         {
165             LOG.debug( "Syntax invalid for '{}'", value );
166             return false;
167         }
168 
169         // We will get the first delivery method
170         int length = strValue.length();
171         int pos = 0;
172         Set<String> pmds = new HashSet<String>();
173 
174         if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1 )
175         {
176             LOG.debug( "Syntax invalid for '{}'", value );
177             return false;
178         }
179 
180         // We have found at least the first pmd,
181         // now iterate through the other ones. We may have
182         // SP* '$' SP* before each pmd.
183         while ( pos < length )
184         {
185             // Skip spaces
186             while ( Strings.isCharASCII( strValue, pos, ' ' ) )
187             {
188                 pos++;
189             }
190 
191             if ( !Strings.isCharASCII( strValue, pos, '$' ) )
192             {
193                 // A '$' was expected
194                 LOG.debug( "Syntax invalid for '{}'", value );
195                 return false;
196             }
197             else
198             {
199                 pos++;
200             }
201 
202             // Skip spaces
203             while ( Strings.isCharASCII( strValue, pos, ' ' ) )
204             {
205                 pos++;
206             }
207 
208             if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1 )
209             {
210                 LOG.debug( "Syntax invalid for '{}'", value );
211                 return false;
212             }
213         }
214 
215         LOG.debug( "Syntax valid for '{}'", value );
216         return true;
217     }
218 }