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.parsers;
21  
22  
23  import java.util.List;
24  
25  import org.apache.directory.api.ldap.model.schema.AttributeType;
26  import org.apache.directory.api.ldap.model.schema.LdapSyntax;
27  import org.apache.directory.api.ldap.model.schema.MatchingRule;
28  import org.apache.directory.api.ldap.model.schema.ObjectClass;
29  import org.apache.directory.api.ldap.model.schema.SchemaObject;
30  
31  
32  /**
33   * Utilities for dealing with various schema descriptions.
34   *
35   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
36   */
37  public final class ParserDescriptionUtils
38  {
39      /**
40       * Private constructor.
41       */
42      private ParserDescriptionUtils()
43      {
44      }
45  
46  
47      /**
48       * Checks two schema objectClasses for an exact match.
49       *
50       * @param oc0 the first objectClass to compare
51       * @param oc1 the second objectClass to compare
52       * @return true if both objectClasses match exactly, false otherwise
53       */
54      public static boolean objectClassesMatch( ObjectClass oc0, ObjectClass oc1 )
55      {
56          // compare all common description parameters
57          if ( !descriptionsMatch( oc0, oc1 ) )
58          {
59              return false;
60          }
61  
62          // compare the objectClass type (AUXILIARY, STRUCTURAL, ABSTRACT)
63          if ( oc0.getType() != oc1.getType() )
64          {
65              return false;
66          }
67  
68          // compare the superior objectClasses (sizes must match)
69          if ( oc0.getSuperiorOids().size() != oc1.getSuperiorOids().size() )
70          {
71              return false;
72          }
73  
74          // compare the superior objectClasses (sizes must match)
75          for ( int i = 0; i < oc0.getSuperiorOids().size(); i++ )
76          {
77              if ( !oc0.getSuperiorOids().get( i ).equals( oc1.getSuperiorOids().get( i ) ) )
78              {
79                  return false;
80              }
81          }
82  
83          // compare the must attributes (sizes must match)
84          for ( int i = 0; i < oc0.getMustAttributeTypeOids().size(); i++ )
85          {
86              if ( !oc0.getMustAttributeTypeOids().get( i ).equals( oc1.getMustAttributeTypeOids().get( i ) ) )
87              {
88                  return false;
89              }
90          }
91  
92          // compare the may attributes (sizes must match)
93          for ( int i = 0; i < oc0.getMayAttributeTypeOids().size(); i++ )
94          {
95              if ( !oc0.getMayAttributeTypeOids().get( i ).equals( oc1.getMayAttributeTypeOids().get( i ) ) )
96              {
97                  return false;
98              }
99          }
100 
101         return true;
102     }
103 
104 
105     /**
106      * Checks two schema attributeTypes for an exact match.
107      *
108      * @param at0 the first attributeType to compare
109      * @param at1 the second attributeType to compare
110      * @return true if both attributeTypes match exactly, false otherwise
111      */
112     public static boolean attributeTypesMatch( AttributeType at0, AttributeType at1 )
113     {
114         // compare all common description parameters
115         if ( !descriptionsMatch( at0, at1 ) )
116         {
117             return false;
118         }
119 
120         // check that the same super type is being used for both attributes
121         if ( !at0.getSuperiorOid().equals( at1.getSuperiorOid() ) )
122         {
123             return false;
124         }
125 
126         // check that the same matchingRule is used by both ATs for EQUALITY
127         if ( !at0.getEqualityOid().equals( at1.getEqualityOid() ) )
128         {
129             return false;
130         }
131 
132         // check that the same matchingRule is used by both ATs for SUBSTRING
133         if ( !at0.getSubstringOid().equals( at1.getSubstringOid() ) )
134         {
135             return false;
136         }
137 
138         // check that the same matchingRule is used by both ATs for ORDERING
139         if ( !at0.getOrderingOid().equals( at1.getOrderingOid() ) )
140         {
141             return false;
142         }
143 
144         // check that the same syntax is used by both ATs
145         if ( !at0.getSyntaxOid().equals( at1.getSyntaxOid() ) )
146         {
147             return false;
148         }
149 
150         // check that the syntax length constraint is the same for both
151         if ( at0.getSyntaxLength() != at1.getSyntaxLength() )
152         {
153             return false;
154         }
155 
156         // check that the ATs have the same single valued flag value
157         if ( at0.isSingleValued() != at1.isSingleValued() )
158         {
159             return false;
160         }
161 
162         // check that the ATs have the same collective flag value
163         if ( at0.isCollective() != at1.isCollective() )
164         {
165             return false;
166         }
167 
168         // check that the ATs have the same user modifiable flag value
169         if ( at0.isUserModifiable() != at1.isUserModifiable() )
170         {
171             return false;
172         }
173 
174         // check that the ATs have the same USAGE
175         if ( at0.getUsage() != at1.getUsage() )
176         {
177             return false;
178         }
179 
180         return true;
181     }
182 
183 
184     /**
185      * Checks to see if two matchingRule match exactly.
186      *
187      * @param matchingRule0 the first matchingRule to compare
188      * @param matchingRule1 the second matchingRule to compare
189      * @return true if the matchingRules match exactly, false otherwise
190      */
191     public static boolean matchingRulesMatch( MatchingRule matchingRule0, MatchingRule matchingRule1 )
192     {
193         // compare all common description parameters
194         if ( !descriptionsMatch( matchingRule0, matchingRule1 ) )
195         {
196             return false;
197         }
198 
199         // check that the syntaxes of the matchingRules match
200         if ( !matchingRule0.getSyntaxOid().equals( matchingRule1.getSyntaxOid() ) )
201         {
202             return false;
203         }
204 
205         return true;
206     }
207 
208 
209     /**
210      * Checks to see if two syntax match exactly.
211      *
212      * @param ldapSyntax0 the first ldapSyntax to compare
213      * @param ldapSyntax1 the second ldapSyntax to compare
214      * @return true if the syntaxes match exactly, false otherwise
215      */
216     public static boolean syntaxesMatch( LdapSyntax ldapSyntax0, LdapSyntax ldapSyntax1 )
217     {
218         return descriptionsMatch( ldapSyntax0, ldapSyntax1 );
219     }
220 
221 
222     /**
223      * Checks if two base schema descriptions match for the common components 
224      * in every schema description.  NOTE: for syntaxes the obsolete flag is 
225      * not compared because doing so would raise an exception since syntax 
226      * descriptions do not support the OBSOLETE flag.
227      * 
228      * @param so0 the first schema description to compare 
229      * @param so1 the second schema description to compare 
230      * @return true if the descriptions match exactly, false otherwise
231      */
232     public static boolean descriptionsMatch( SchemaObject so0, SchemaObject so1 )
233     {
234         // check that the OID matches
235         if ( !so0.getOid().equals( so1.getOid() ) )
236         {
237             return false;
238         }
239 
240         // check that the obsolete flag is equal but not for syntaxes
241         if ( ( ( so0 instanceof LdapSyntax ) || ( so1 instanceof LdapSyntax ) ) && so0.isObsolete() != so1.isObsolete() )
242         {
243             return false;
244         }
245 
246         // check that the description matches
247         if ( !so0.getDescription().equals( so1.getDescription() ) )
248         {
249             return false;
250         }
251 
252         // check alias names for exact match
253         if ( !aliasNamesMatch( so0, so1 ) )
254         {
255             return false;
256         }
257 
258         // check extensions for exact match
259         if ( !extensionsMatch( so0, so1 ) )
260         {
261             return false;
262         }
263 
264         return true;
265     }
266 
267 
268     /**
269      * Checks to see if the extensions of a schema description match another
270      * description.  The order of the extension values must match for a true
271      * return.
272      *
273      * @param lsd0 the first schema description to compare the extensions of
274      * @param lsd1 the second schema description to compare the extensions of
275      * @return true if the extensions match exactly, false otherwise
276      */
277     public static boolean extensionsMatch( SchemaObject lsd0, SchemaObject lsd1 )
278     {
279         // check sizes first
280         if ( lsd0.getExtensions().size() != lsd1.getExtensions().size() )
281         {
282             return false;
283         }
284 
285         // check contents and order of extension values must match
286         for ( String key : lsd0.getExtensions().keySet() )
287         {
288             List<String> values0 = lsd0.getExtensions().get( key );
289             List<String> values1 = lsd1.getExtensions().get( key );
290 
291             // if the key is not present in asd1
292             if ( values1 == null )
293             {
294                 return false;
295             }
296 
297             for ( int i = 0; i < values0.size(); i++ )
298             {
299                 if ( !values0.get( i ).equals( values1.get( i ) ) )
300                 {
301                     return false;
302                 }
303             }
304         }
305 
306         return true;
307     }
308 
309 
310     /**
311      * Checks to see if the alias names of a schema description match another 
312      * description.  The order of the alias names do matter.
313      *
314      * @param so0 the schema description to compare
315      * @param so1 the schema description to compare
316      * @return true if alias names match exactly, false otherwise
317      */
318     public static boolean aliasNamesMatch( SchemaObject so0, SchemaObject so1 )
319     {
320         // check sizes first
321         if ( so0.getNames().size() != so1.getNames().size() )
322         {
323             return false;
324         }
325 
326         // check contents and order must match too
327         for ( int i = 0; i < so0.getNames().size(); i++ )
328         {
329             if ( !so0.getNames().get( i ).equals( so1.getNames().get( i ) ) )
330             {
331                 return false;
332             }
333         }
334 
335         return true;
336     }
337 }