1 17 package org.apache.ldap.server.schema; 18 19 20 import org.apache.ldap.common.filter.ExprNode; 21 import org.apache.ldap.common.filter.PresenceNode; 22 import org.apache.ldap.common.filter.SimpleNode; 23 import org.apache.ldap.common.message.LockableAttributeImpl; 24 import org.apache.ldap.common.message.LockableAttributesImpl; 25 import org.apache.ldap.common.name.LdapName; 26 import org.apache.ldap.common.schema.*; 27 import org.apache.ldap.common.util.SingletonEnumeration; 28 import org.apache.ldap.server.RootNexus; 29 import org.apache.ldap.server.interceptor.BaseInterceptor; 30 import org.apache.ldap.server.interceptor.InterceptorContext; 31 import org.apache.ldap.server.interceptor.NextInterceptor; 32 import org.apache.ldap.server.db.ResultFilteringEnumeration; 33 import org.apache.ldap.server.db.SearchResultFilter; 34 import org.apache.ldap.server.invocation.List; 35 import org.apache.ldap.server.invocation.Lookup; 36 import org.apache.ldap.server.invocation.LookupWithAttrIds; 37 import org.apache.ldap.server.invocation.Search; 38 import org.apache.ldap.server.jndi.ServerLdapContext; 39 import org.apache.ldap.server.schema.AttributeTypeRegistry; 40 import org.apache.ldap.server.schema.GlobalRegistries; 41 42 import javax.naming.NamingEnumeration ; 43 import javax.naming.NamingException ; 44 import javax.naming.directory.Attribute ; 45 import javax.naming.directory.Attributes ; 46 import javax.naming.directory.SearchControls ; 47 import javax.naming.directory.SearchResult ; 48 import javax.naming.ldap.LdapContext ; 49 import java.util.Collections ; 50 import java.util.HashSet ; 51 import java.util.Iterator ; 52 import java.util.Set ; 53 54 55 62 public class SchemaService extends BaseInterceptor 63 { 64 private static final String BINARY_KEY = "java.naming.ldap.attributes.binary"; 65 66 69 private RootNexus nexus; 70 71 74 private BinaryAttributeFilter binaryAttributeFilter; 75 76 79 private GlobalRegistries globalRegistries; 80 81 private AttributeTypeRegistry attributeRegistry; 82 83 86 private String subentryDn; 87 88 89 92 public SchemaService() 93 { 94 } 95 96 97 public void init( InterceptorContext ctx ) throws NamingException 98 { 99 this.nexus = ctx.getRootNexus(); 100 this.globalRegistries = ctx.getGlobalRegistries(); 101 attributeRegistry = globalRegistries.getAttributeTypeRegistry(); 102 binaryAttributeFilter = new BinaryAttributeFilter(); 103 104 String subschemaSubentry = ( String ) nexus.getRootDSE().get( "subschemaSubentry" ).get(); 106 subentryDn = new LdapName( subschemaSubentry ).toString().toLowerCase(); 107 } 108 109 110 public void destroy() 111 { 112 } 113 114 115 protected void process( NextInterceptor nextInterceptor, List call ) throws NamingException 116 { 117 nextInterceptor.process( call ); 118 119 NamingEnumeration e; 120 ResultFilteringEnumeration retval; 121 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 122 e = ( NamingEnumeration ) call.getReturnValue(); 123 retval = new ResultFilteringEnumeration( e, new SearchControls (), ctx, binaryAttributeFilter ); 124 call.setReturnValue( retval ); 125 } 126 127 128 protected void process( NextInterceptor nextInterceptor, Search call ) throws NamingException 129 { 130 if ( !subentryDn.equals( call.getBaseName().toString() ) ) 132 { 133 nextInterceptor.process( call ); 134 return; 135 } 136 137 boolean bypass = false; 138 SearchControls searchControls = call.getControls(); 139 ExprNode filter = call.getFilter(); 140 if ( searchControls.getSearchScope() == SearchControls.OBJECT_SCOPE && 141 filter instanceof SimpleNode ) 142 { 143 SimpleNode node = ( SimpleNode ) filter; 144 145 if ( node.getAttribute().equalsIgnoreCase( "objectClass" ) && 146 node.getValue().equalsIgnoreCase( "subschema" ) && 147 node.getAssertionType() == SimpleNode.EQUALITY 148 ) 149 { 150 Attributes attrs = getSubschemaEntry( searchControls.getReturningAttributes() ); 152 SearchResult result = new SearchResult ( call.getBaseName().toString(), null, attrs ); 153 SingletonEnumeration e = new SingletonEnumeration( result ); 154 call.setReturnValue( e ); 155 bypass = true; 156 } 157 } 158 else if ( searchControls.getSearchScope() == SearchControls.OBJECT_SCOPE && 159 filter instanceof PresenceNode ) 160 { 161 PresenceNode node = ( PresenceNode ) filter; 162 163 if ( node.getAttribute().equalsIgnoreCase( "objectClass" ) ) 164 { 165 Attributes attrs = getSubschemaEntry( searchControls.getReturningAttributes() ); 167 SearchResult result = new SearchResult ( call.getBaseName().toString(), null, attrs ); 168 SingletonEnumeration e = new SingletonEnumeration( result ); 169 call.setReturnValue( e ); 170 bypass = true; 171 } 172 } 173 174 if ( !bypass ) 175 { 176 nextInterceptor.process( call ); 177 } 178 179 if ( searchControls.getReturningAttributes() != null ) 180 { 181 return; 182 } 183 184 NamingEnumeration e; 185 ResultFilteringEnumeration retval; 186 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 187 e = ( NamingEnumeration ) call.getReturnValue(); 188 retval = new ResultFilteringEnumeration( e, searchControls, ctx, binaryAttributeFilter ); 189 call.setReturnValue( retval ); 190 } 191 192 193 private Attributes getSubschemaEntry( String [] ids ) throws NamingException 194 { 195 if ( ids == null ) 196 { 197 return new LockableAttributesImpl(); 198 } 199 200 HashSet set = new HashSet ( ids.length ); 201 LockableAttributesImpl attrs = new LockableAttributesImpl(); 202 LockableAttributeImpl attr = null; 203 204 for ( int ii = 0; ii < ids.length; ii++ ) 205 { 206 set.add( ids[ii].toLowerCase() ); 207 } 208 209 210 if ( set.contains( "objectclasses" ) ) 211 { 212 attr = new LockableAttributeImpl( attrs, "objectClasses" ); 213 Iterator list = globalRegistries.getObjectClassRegistry().list(); 214 while ( list.hasNext() ) 215 { 216 ObjectClass oc = ( ObjectClass ) list.next(); 217 attr.add( SchemaUtils.render( oc ).toString() ); 218 } 219 attrs.put( attr ); 220 } 221 222 if ( set.contains( "attributetypes" ) ) 223 { 224 attr = new LockableAttributeImpl( attrs, "attributeTypes" ); 225 Iterator list = globalRegistries.getAttributeTypeRegistry().list(); 226 while ( list.hasNext() ) 227 { 228 AttributeType at = ( AttributeType ) list.next(); 229 attr.add( SchemaUtils.render( at ).toString() ); 230 } 231 attrs.put( attr ); 232 } 233 234 if ( set.contains( "matchingrules" ) ) 235 { 236 attr = new LockableAttributeImpl( attrs, "matchingRules" ); 237 Iterator list = globalRegistries.getMatchingRuleRegistry().list(); 238 while ( list.hasNext() ) 239 { 240 MatchingRule mr = ( MatchingRule ) list.next(); 241 attr.add( SchemaUtils.render( mr ).toString() ); 242 } 243 attrs.put( attr ); 244 } 245 246 if ( set.contains( "matchingruleuse" ) ) 247 { 248 attr = new LockableAttributeImpl( attrs, "matchingRuleUse" ); 249 Iterator list = globalRegistries.getMatchingRuleUseRegistry().list(); 250 while ( list.hasNext() ) 251 { 252 MatchingRuleUse mru = ( MatchingRuleUse ) list.next(); 253 attr.add( SchemaUtils.render( mru ).toString() ); 254 } 255 attrs.put( attr ); 256 } 257 258 if ( set.contains( "ldapsyntaxes" ) ) 259 { 260 attr = new LockableAttributeImpl( attrs, "ldapSyntaxes" ); 261 Iterator list = globalRegistries.getSyntaxRegistry().list(); 262 while ( list.hasNext() ) 263 { 264 Syntax syntax = ( Syntax ) list.next(); 265 attr.add( SchemaUtils.render( syntax ).toString() ); 266 } 267 attrs.put( attr ); 268 } 269 270 if ( set.contains( "ditcontentrules" ) ) 271 { 272 attr = new LockableAttributeImpl( attrs, "dITContentRules" ); 273 Iterator list = globalRegistries.getDitContentRuleRegistry().list(); 274 while ( list.hasNext() ) 275 { 276 DITContentRule dcr = ( DITContentRule ) list.next(); 277 attr.add( SchemaUtils.render( dcr ).toString() ); 278 } 279 attrs.put( attr ); 280 } 281 282 if ( set.contains( "ditstructurerules" ) ) 283 { 284 attr = new LockableAttributeImpl( attrs, "dITStructureRules" ); 285 Iterator list = globalRegistries.getDitStructureRuleRegistry().list(); 286 while ( list.hasNext() ) 287 { 288 DITStructureRule dsr = ( DITStructureRule ) list.next(); 289 attr.add( SchemaUtils.render( dsr ).toString() ); 290 } 291 attrs.put( attr ); 292 } 293 294 if ( set.contains( "nameforms" ) ) 295 { 296 attr = new LockableAttributeImpl( attrs, "nameForms" ); 297 Iterator list = globalRegistries.getNameFormRegistry().list(); 298 while ( list.hasNext() ) 299 { 300 NameForm nf = ( NameForm ) list.next(); 301 attr.add( SchemaUtils.render( nf ).toString() ); 302 } 303 attrs.put( attr ); 304 } 305 306 attr = new LockableAttributeImpl( attrs, "objectClass" ); 308 attr.add( "top" ); 309 attr.add( "subschema" ); 310 attrs.put( attr ); 311 312 attrs.put( "cn", "schema" ); 314 315 return attrs; 316 } 317 318 319 protected void process( NextInterceptor nextInterceptor, Lookup call ) throws NamingException 320 { 321 nextInterceptor.process( call ); 322 323 ServerLdapContext ctx = ( ServerLdapContext ) call.getContextStack().peek(); 324 Attributes attributes = ( Attributes ) call.getReturnValue(); 325 Attributes retval = ( Attributes ) attributes.clone(); 326 doFilter( ctx, retval ); 327 call.setReturnValue( retval ); 328 } 329 330 331 protected void process( NextInterceptor nextInterceptor, LookupWithAttrIds call ) throws NamingException 332 { 333 nextInterceptor.process( call ); 334 335 ServerLdapContext ctx = ( ServerLdapContext ) call.getContextStack().peek(); 336 Attributes attributes = ( Attributes ) call.getReturnValue(); 337 if ( attributes == null ) 338 { 339 return; 340 } 341 342 Attributes retval = ( Attributes ) attributes.clone(); 343 doFilter( ctx, retval ); 344 call.setReturnValue( retval ); 345 } 346 347 348 private void doFilter( LdapContext ctx, Attributes entry ) 349 throws NamingException 350 { 351 Set binaries; 353 354 String binaryIds = ( String ) ctx.getEnvironment().get( BINARY_KEY ); 356 357 if ( binaryIds == null ) 358 { 359 binaries = Collections.EMPTY_SET; 360 } 361 else 362 { 363 String [] binaryArray = binaryIds.split( " " ); 364 365 binaries = new HashSet ( binaryArray.length ); 366 367 for ( int ii = 0; ii < binaryArray.length; ii++ ) 368 { 369 AttributeType type = attributeRegistry.lookup( binaryArray[ii] ); 370 371 binaries.add( type ); 372 } 373 } 374 375 379 NamingEnumeration list = entry.getIDs(); 380 381 while ( list.hasMore() ) 382 { 383 String id = ( String ) list.next(); 384 385 AttributeType type = null; 386 387 boolean asBinary = false; 388 389 if ( attributeRegistry.hasAttributeType( id ) ) 390 { 391 type = attributeRegistry.lookup( id ); 392 } 393 394 if ( type != null ) 395 { 396 asBinary = !type.getSyntax().isHumanReadible(); 397 398 asBinary = asBinary || binaries.contains( type ); 399 } 400 401 if ( asBinary ) 402 { 403 Attribute attribute = entry.get( id ); 404 405 Attribute binary = new LockableAttributeImpl( id ); 406 407 for ( int ii = 0; ii < attribute.size(); ii++ ) 408 { 409 Object value = attribute.get( ii ); 410 411 if ( value instanceof String ) 412 { 413 binary.add( ii, ( ( String ) value ).getBytes() ); 414 } 415 else 416 { 417 binary.add( ii, value ); 418 } 419 } 420 421 entry.remove( id ); 422 423 entry.put( binary ); 424 } 425 } 426 } 427 428 429 437 private class BinaryAttributeFilter implements SearchResultFilter 438 { 439 public BinaryAttributeFilter() 440 { 441 } 442 443 444 public boolean accept( LdapContext ctx, SearchResult result, SearchControls controls ) throws NamingException 445 { 446 doFilter( ctx, result.getAttributes() ); 447 return true; 448 } 449 } 450 } 451 | Popular Tags |