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