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.parsers;
021
022
023 import java.util.List;
024
025 import javax.naming.NamingException;
026
027 import org.apache.directory.shared.ldap.schema.AttributeType;
028 import org.apache.directory.shared.ldap.schema.LdapSyntax;
029 import org.apache.directory.shared.ldap.schema.MatchingRule;
030 import org.apache.directory.shared.ldap.schema.ObjectClass;
031 import org.apache.directory.shared.ldap.schema.SchemaObject;
032
033
034
035 /**
036 * Utilities for dealing with various schema descriptions.
037 *
038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039 * @version $Rev$, $Date$
040 */
041 public class ParserDescriptionUtils
042 {
043 /**
044 * Checks two schema objectClasses for an exact match.
045 *
046 * @param ocd0 the first objectClass to compare
047 * @param ocd1 the second objectClass to compare
048 * @return true if both objectClasses match exactly, false otherwise
049 */
050 public static boolean objectClassesMatch( ObjectClass oc0, ObjectClass oc1 ) throws NamingException
051 {
052 // compare all common description parameters
053 if ( ! descriptionsMatch( oc0, oc1 ) )
054 {
055 return false;
056 }
057
058 // compare the objectClass type (AUXILIARY, STRUCTURAL, ABSTRACT)
059 if ( oc0.getType() != oc1.getType() )
060 {
061 return false;
062 }
063
064 // compare the superior objectClasses (sizes must match)
065 if ( oc0.getSuperiorOids().size() != oc1.getSuperiorOids().size() )
066 {
067 return false;
068 }
069
070 // compare the superior objectClasses (sizes must match)
071 for ( int i = 0; i < oc0.getSuperiorOids().size(); i++ )
072 {
073 if ( ! oc0.getSuperiorOids().get( i ).equals( oc1.getSuperiorOids().get( i ) ) )
074 {
075 return false;
076 }
077 }
078
079 // compare the must attributes (sizes must match)
080 for ( int i = 0; i < oc0.getMustAttributeTypeOids().size(); i++ )
081 {
082 if ( ! oc0.getMustAttributeTypeOids().get( i ).equals( oc1.getMustAttributeTypeOids().get( i ) ) )
083 {
084 return false;
085 }
086 }
087
088 // compare the may attributes (sizes must match)
089 for ( int i = 0; i < oc0.getMayAttributeTypeOids().size(); i++ )
090 {
091 if ( ! oc0.getMayAttributeTypeOids().get( i ).equals( oc1.getMayAttributeTypeOids().get( i ) ) )
092 {
093 return false;
094 }
095 }
096
097 return true;
098 }
099
100
101 /**
102 * Checks two schema attributeTypes for an exact match.
103 *
104 * @param atd0 the first attributeType to compare
105 * @param atd1 the second attributeType to compare
106 * @return true if both attributeTypes match exactly, false otherwise
107 */
108 public static boolean attributeTypesMatch( AttributeType at0, AttributeType at1 )
109 {
110 // compare all common description parameters
111 if ( ! descriptionsMatch( at0, at1 ) )
112 {
113 return false;
114 }
115
116 // check that the same super type is being used for both attributes
117 if ( ! at0.getSuperiorOid().equals( at1.getSuperiorOid() ) )
118 {
119 return false;
120 }
121
122 // check that the same matchingRule is used by both ATs for EQUALITY
123 if ( ! at0.getEqualityOid().equals( at1.getEqualityOid() ) )
124 {
125 return false;
126 }
127
128 // check that the same matchingRule is used by both ATs for SUBSTRING
129 if ( ! at0.getSubstringOid().equals( at1.getSubstringOid() ) )
130 {
131 return false;
132 }
133
134 // check that the same matchingRule is used by both ATs for ORDERING
135 if ( ! at0.getOrderingOid().equals( at1.getOrderingOid() ) )
136 {
137 return false;
138 }
139
140 // check that the same syntax is used by both ATs
141 if ( ! at0.getSyntaxOid().equals( at1.getSyntaxOid() ) )
142 {
143 return false;
144 }
145
146 // check that the syntax length constraint is the same for both
147 if ( at0.getSyntaxLength() != at1.getSyntaxLength() )
148 {
149 return false;
150 }
151
152 // check that the ATs have the same single valued flag value
153 if ( at0.isSingleValued() != at1.isSingleValued() )
154 {
155 return false;
156 }
157
158 // check that the ATs have the same collective flag value
159 if ( at0.isCollective() != at1.isCollective() )
160 {
161 return false;
162 }
163
164 // check that the ATs have the same user modifiable flag value
165 if ( at0.isUserModifiable() != at1.isUserModifiable() )
166 {
167 return false;
168 }
169
170 // check that the ATs have the same USAGE
171 if ( at0.getUsage() != at1.getUsage() )
172 {
173 return false;
174 }
175
176 return true;
177 }
178
179
180 /**
181 * Checks to see if two matchingRule match exactly.
182 *
183 * @param mrd0 the first matchingRule to compare
184 * @param mrd1 the second matchingRule to compare
185 * @return true if the matchingRules match exactly, false otherwise
186 */
187 public static boolean matchingRulesMatch( MatchingRule matchingRule0, MatchingRule matchingRule1 )
188 {
189 // compare all common description parameters
190 if ( ! descriptionsMatch( matchingRule0, matchingRule1 ) )
191 {
192 return false;
193 }
194
195 // check that the syntaxes of the matchingRules match
196 if ( ! matchingRule0.getSyntaxOid().equals( matchingRule1.getSyntaxOid() ) )
197 {
198 return false;
199 }
200
201 return true;
202 }
203
204
205 /**
206 * Checks to see if two syntax match exactly.
207 *
208 * @param ldapSyntax0 the first ldapSyntax to compare
209 * @param ldapSyntax1 the second ldapSyntax to compare
210 * @return true if the syntaxes match exactly, false otherwise
211 */
212 public static boolean syntaxesMatch( LdapSyntax ldapSyntax0, LdapSyntax ldapSyntax1 )
213 {
214 return descriptionsMatch( ldapSyntax0, ldapSyntax1 );
215 }
216
217
218 /**
219 * Checks if two base schema descriptions match for the common components
220 * in every schema description. NOTE: for syntaxes the obsolete flag is
221 * not compared because doing so would raise an exception since syntax
222 * descriptions do not support the OBSOLETE flag.
223 *
224 * @param lsd0 the first schema description to compare
225 * @param lsd1 the second schema description to compare
226 * @return true if the descriptions match exactly, false otherwise
227 */
228 public static boolean descriptionsMatch( SchemaObject so0, SchemaObject so1 )
229 {
230 // check that the OID matches
231 if ( ! so0.getOid().equals( so1.getOid() ) )
232 {
233 return false;
234 }
235
236 // check that the obsolete flag is equal but not for syntaxes
237 if ( ( so0 instanceof LdapSyntax ) || ( so1 instanceof LdapSyntax ) )
238 {
239 if ( so0.isObsolete() != so1.isObsolete() )
240 {
241 return false;
242 }
243 }
244
245 // check that the description matches
246 if ( ! so0.getDescription().equals( so1.getDescription() ) )
247 {
248 return false;
249 }
250
251 // check alias names for exact match
252 if ( ! aliasNamesMatch( so0, so1 ) )
253 {
254 return false;
255 }
256
257 // check extensions for exact match
258 if ( ! extensionsMatch( so0, so1 ) )
259 {
260 return false;
261 }
262
263 return true;
264 }
265
266
267 /**
268 * Checks to see if the extensions of a schema description match another
269 * description. The order of the extension values must match for a true
270 * return.
271 *
272 * @param lsd0 the first schema description to compare the extensions of
273 * @param lsd1 the second schema description to compare the extensions of
274 * @return true if the extensions match exactly, false otherwise
275 */
276 public static boolean extensionsMatch( SchemaObject lsd0, SchemaObject lsd1 )
277 {
278 // check sizes first
279 if ( lsd0.getExtensions().size() != lsd1.getExtensions().size() )
280 {
281 return false;
282 }
283
284 // check contents and order of extension values must match
285 for ( String key : lsd0.getExtensions().keySet() )
286 {
287 List<String> values0 = lsd0.getExtensions().get( key );
288 List<String> values1 = lsd1.getExtensions().get( key );
289
290 // if the key is not present in asd1
291 if ( values1 == null )
292 {
293 return false;
294 }
295
296 for ( int i = 0; i < values0.size(); i++ )
297 {
298 if ( ! values0.get( i ).equals( values1.get( i ) ) )
299 {
300 return false;
301 }
302 }
303 }
304
305 return true;
306 }
307
308
309 /**
310 * Checks to see if the alias names of a schema description match another
311 * description. The order of the alias names do matter.
312 *
313 * @param asd0 the schema description to compare
314 * @param asd1 the schema description to compare
315 * @return true if alias names match exactly, false otherwise
316 */
317 public static boolean aliasNamesMatch( SchemaObject so0, SchemaObject so1 )
318 {
319 // check sizes first
320 if ( so0.getNames().size() != so1.getNames().size() )
321 {
322 return false;
323 }
324
325 // check contents and order must match too
326 for ( int i = 0; i < so0.getNames().size(); i++ )
327 {
328 if ( ! so0.getNames().get( i ).equals( so1.getNames().get( i ) ) )
329 {
330 return false;
331 }
332 }
333
334 return true;
335 }
336 }