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 }