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.syntaxes;
021
022
023 import java.util.HashSet;
024 import java.util.Set;
025
026 import org.apache.directory.shared.ldap.constants.SchemaConstants;
027 import org.apache.directory.shared.ldap.schema.AbstractSyntaxChecker;
028 import org.apache.directory.shared.ldap.util.StringTools;
029
030
031 /**
032 * A SyntaxChecker which verifies that a value is a delivery method
033 * according to RFC 4517.
034 *
035 * From RFC 4517 & RFC 4512:
036 *
037 * DeliveryMethod = pdm *( WSP DOLLAR WSP pdm )
038 *
039 * pdm = "any" | "mhs" | "physical" | "telex" | "teletex" |
040 * "g3fax" | "g4fax" | "ia5" | "videotex" | "telephone"
041 *
042 * WSP = 0*SPACE ; zero or more " "
043 * DOLLAR = %x24 ; dollar sign ("$")
044 * SPACE = %x20 ; space (" ")
045 *
046 *
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 * @version $Rev$
049 */
050 public class DeliveryMethodSyntaxChecker extends AbstractSyntaxChecker
051 {
052 private static final String[] PDMS =
053 {
054 "any", "mhs", "physical", "telex", "teletex",
055 "g3fax", "g4fax", "ia5", "videotex", "telephone"
056 };
057
058 /** The Set which contains the delivery methods */
059 private static final Set<String> DELIVERY_METHODS = new HashSet<String>();
060
061 /** Initialization of the delivery methods set */
062 static
063 {
064 for ( String country:PDMS )
065 {
066 DELIVERY_METHODS.add( country );
067 }
068 }
069
070
071 /**
072 *
073 * Creates a new instance of DeliveryMethodSyntaxChecker.
074 *
075 */
076 public DeliveryMethodSyntaxChecker()
077 {
078 super( SchemaConstants.DELIVERY_METHOD_SYNTAX );
079 }
080
081 /**
082 *
083 * Creates a new instance of DeliveryMethodSyntaxChecker.
084 *
085 * @param oid the oid to associate with this new SyntaxChecker
086 *
087 */
088 protected DeliveryMethodSyntaxChecker( String oid )
089 {
090 super( oid );
091 }
092
093 /**
094 *
095 * Check if the string contains a delivery method which has
096 * not already been found.
097 *
098 * @param strValue The string we want to look into for a PDM
099 * @param pos The current position in the string
100 * @param pdms The set containing all the PDM
101 * @return if a Prefered Delivery Method is found in the given string, returns
102 * its position, otherwise, returns -1
103 */
104 private int isPdm( String strValue, int pos, Set<String> pdms )
105 {
106 int start = pos;
107
108 while ( StringTools.isAlphaDigit( strValue, pos ) )
109 {
110 pos++;
111 }
112
113 // No ascii string, this is not a delivery method
114 if ( pos == start )
115 {
116 return -1;
117 }
118
119 String pdm = strValue.substring( start, pos );
120
121 if ( ! DELIVERY_METHODS.contains( pdm ) )
122 {
123 // The delivery method is unknown
124 return -1;
125 }
126 else
127 {
128 if ( pdms.contains( pdm ) )
129 {
130 // The delivery method has already been found
131 return -1;
132 }
133 else
134 {
135 pdms.add( pdm );
136 return pos;
137 }
138 }
139 }
140
141 /* (non-Javadoc)
142 * @see org.apache.directory.shared.ldap.schema.SyntaxChecker#isValidSyntax(java.lang.Object)
143 */
144 public boolean isValidSyntax( Object value )
145 {
146 String strValue = null;
147
148 if ( value == null )
149 {
150 return false;
151 }
152
153 if ( value instanceof String )
154 {
155 strValue = ( String ) value;
156 }
157 else if ( value instanceof byte[] )
158 {
159 strValue = StringTools.utf8ToString( ( byte[] ) value );
160 }
161 else
162 {
163 strValue = value.toString();
164 }
165
166 if ( strValue.length() == 0 )
167 {
168 return false;
169 }
170
171 // We will get the first delivery method
172 int length = strValue.length();
173 int pos = 0;
174 Set<String> pmds = new HashSet<String>();
175
176 if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1)
177 {
178 return false;
179 }
180
181 // We have found at least the first pmd,
182 // now iterate through the other ones. We may have
183 // SP* '$' SP* before each pmd.
184 while ( pos < length )
185 {
186 // Skip spaces
187 while ( StringTools.isCharASCII( strValue, pos, ' ' ) )
188 {
189 pos++;
190 }
191
192 if ( ! StringTools.isCharASCII( strValue, pos, '$' ) )
193 {
194 // A '$' was expected
195 return false;
196 }
197 else
198 {
199 pos++;
200 }
201
202 // Skip spaces
203 while ( StringTools.isCharASCII( strValue, pos, ' ' ) )
204 {
205 pos++;
206 }
207
208 if ( ( pos = isPdm( strValue, pos, pmds ) ) == -1 )
209 {
210 return false;
211 }
212 }
213
214 return true;
215 }
216 }