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.server.core.schema;
021
022
023 import java.util.ArrayList;
024 import java.util.HashMap;
025 import java.util.HashSet;
026 import java.util.List;
027 import java.util.Map;
028 import java.util.Set;
029
030 import javax.naming.NamingException;
031 import javax.naming.directory.SearchControls;
032
033 import org.apache.directory.server.constants.ServerDNConstants;
034 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
035 import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
036 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
037 import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
038 import org.apache.directory.server.core.partition.Partition;
039 import org.apache.directory.server.i18n.I18n;
040 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants;
041 import org.apache.directory.shared.ldap.constants.SchemaConstants;
042 import org.apache.directory.shared.ldap.entry.StringValue;
043 import org.apache.directory.shared.ldap.entry.DefaultServerAttribute;
044 import org.apache.directory.shared.ldap.entry.EntryAttribute;
045 import org.apache.directory.shared.ldap.entry.Modification;
046 import org.apache.directory.shared.ldap.entry.ModificationOperation;
047 import org.apache.directory.shared.ldap.entry.ServerEntry;
048 import org.apache.directory.shared.ldap.entry.ServerModification;
049 import org.apache.directory.shared.ldap.filter.AndNode;
050 import org.apache.directory.shared.ldap.filter.BranchNode;
051 import org.apache.directory.shared.ldap.filter.EqualityNode;
052 import org.apache.directory.shared.ldap.filter.ExprNode;
053 import org.apache.directory.shared.ldap.filter.OrNode;
054 import org.apache.directory.shared.ldap.filter.PresenceNode;
055 import org.apache.directory.shared.ldap.filter.SearchScope;
056 import org.apache.directory.shared.ldap.filter.SimpleNode;
057 import org.apache.directory.shared.ldap.message.AliasDerefMode;
058 import org.apache.directory.shared.ldap.name.DN;
059 import org.apache.directory.shared.ldap.name.RDN;
060 import org.apache.directory.shared.ldap.schema.AttributeType;
061 import org.apache.directory.shared.ldap.schema.AttributeTypeOptions;
062 import org.apache.directory.shared.ldap.schema.MatchingRule;
063 import org.apache.directory.shared.ldap.schema.ObjectClass;
064 import org.apache.directory.shared.ldap.schema.SchemaManager;
065 import org.apache.directory.shared.ldap.schema.loader.ldif.SchemaEntityFactory;
066 import org.apache.directory.shared.ldap.schema.registries.Schema;
067 import org.apache.directory.shared.ldap.schema.syntaxCheckers.NumericOidSyntaxChecker;
068 import org.apache.directory.shared.ldap.util.DateUtils;
069 import org.slf4j.Logger;
070 import org.slf4j.LoggerFactory;
071
072
073 /**
074 * A specialized data access object for managing schema objects in the
075 * schema partition.
076 *
077 * WARNING:
078 * This dao operates directly on a partition. Hence no interceptors are available
079 * to perform the various expected services of respective interceptors. Take care
080 * to normalize all filters and distinguished names.
081 *
082 * A single write operation exists for enabling schemas needed for operating indices
083 * in partitions and enabling schemas that are dependencies of other schemas that
084 * are enabled. In both these limited cases there is no need to worry about issues
085 * with a lack of replication propagation because these same updates will take place
086 * on replicas when the original operation is propagated or when replicas start up.
087 *
088 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
089 * @version $Rev$
090 */
091 public class SchemaPartitionDaoImpl implements SchemaPartitionDao
092 {
093 /** static class logger */
094 private final Logger LOG = LoggerFactory.getLogger( getClass() );
095 private static final NumericOidSyntaxChecker NUMERIC_OID_CHECKER = new NumericOidSyntaxChecker();
096 private static final String[] SCHEMA_ATTRIBUTES = new String[]
097 { SchemaConstants.CREATORS_NAME_AT_OID, "m-dependencies", SchemaConstants.OBJECT_CLASS_AT_OID,
098 SchemaConstants.CN_AT_OID, "m-disabled" };
099
100 private final Partition partition;
101 private final SchemaEntityFactory factory;
102 private final SchemaManager schemaManager;
103
104 private final String M_NAME_OID;
105 private final String CN_OID;
106 private final String M_OID_OID;
107 private final String OBJECTCLASS_OID;
108 private final String M_SYNTAX_OID;
109 private final String M_ORDERING_OID;
110 private final String M_SUBSTRING_OID;
111 private final String M_EQUALITY_OID;
112 private final String M_SUP_ATTRIBUTE_TYPE_OID;
113 private final String M_MUST_OID;
114 private final String M_MAY_OID;
115 private final String M_AUX_OID;
116 private final String M_OC_OID;
117 private final String M_SUP_OBJECT_CLASS_OID;
118 private final String M_DEPENDENCIES_OID;
119
120 private final Set<AttributeTypeOptions> schemaAttributesToReturn = new HashSet<AttributeTypeOptions>();
121 private final AttributeType disabledAttributeType;
122
123
124 /**
125 * Creates a schema dao object backing information within a schema partition.
126 *
127 * @param partition the schema partition
128 * @param registries the bootstrap registries that were used to start up the schema partition
129 * @throws NamingException if there are problems initializing this schema partion dao
130 */
131 public SchemaPartitionDaoImpl( Partition partition, SchemaManager schemaManager ) throws Exception
132 {
133 this.partition = partition;
134 this.factory = new SchemaEntityFactory();
135 this.schemaManager = schemaManager;
136
137 this.M_NAME_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_NAME_AT );
138 this.CN_OID = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.CN_AT );
139 this.disabledAttributeType = schemaManager.lookupAttributeTypeRegistry( MetaSchemaConstants.M_DISABLED_AT );
140 this.M_OID_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_OID_AT );
141 this.OBJECTCLASS_OID = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.OBJECT_CLASS_AT );
142 this.M_SYNTAX_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SYNTAX_AT );
143 this.M_ORDERING_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_ORDERING_AT );
144 this.M_EQUALITY_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_EQUALITY_AT );
145 this.M_SUBSTRING_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUBSTR_AT );
146 this.M_SUP_ATTRIBUTE_TYPE_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT );
147 this.M_MUST_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_MUST_AT );
148 this.M_MAY_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_MAY_AT );
149 this.M_AUX_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_AUX_AT );
150 this.M_OC_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_OC_AT );
151 this.M_SUP_OBJECT_CLASS_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT );
152 this.M_DEPENDENCIES_OID = schemaManager.getAttributeTypeRegistry().getOidByName( MetaSchemaConstants.M_DEPENDENCIES_AT );
153
154 for ( String attrId : SCHEMA_ATTRIBUTES )
155 {
156 AttributeTypeOptions ato = new AttributeTypeOptions( schemaManager.lookupAttributeTypeRegistry( attrId ) );
157 schemaAttributesToReturn.add( ato );
158 }
159 }
160
161
162 /* (non-Javadoc)
163 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchemas()
164 */
165 public Map<String, Schema> getSchemas() throws Exception
166 {
167 Map<String, Schema> schemas = new HashMap<String, Schema>();
168 EntryFilteringCursor list = listSchemas();
169
170 while ( list.next() )
171 {
172 ServerEntry sr = list.get();
173 Schema schema = factory.getSchema( sr );
174 schemas.put( schema.getSchemaName(), schema );
175 }
176
177 return schemas;
178 }
179
180
181 /* (non-Javadoc)
182 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchemaNames()
183 */
184 public Set<String> getSchemaNames() throws Exception
185 {
186 Set<String> schemaNames = new HashSet<String>();
187 EntryFilteringCursor list = listSchemas();
188
189 while ( list.next() )
190 {
191 ServerEntry sr = list.get();
192 schemaNames.add( sr.get( SchemaConstants.CN_AT ).getString() );
193 }
194
195 return schemaNames;
196 }
197
198
199 private EntryFilteringCursor listSchemas() throws Exception
200 {
201 DN base = new DN( SchemaConstants.OU_SCHEMA );
202 base.normalize( schemaManager.getNormalizerMapping() );
203 ExprNode filter = new EqualityNode<String>( schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.OBJECT_CLASS_AT ),
204 new StringValue( MetaSchemaConstants.META_SCHEMA_OC ) );
205
206 SearchOperationContext searchContext = new SearchOperationContext( null );
207 searchContext.setDn( base );
208 searchContext.setScope( SearchScope.ONELEVEL );
209 searchContext.setReturningAttributes( schemaAttributesToReturn );
210 searchContext.setFilter( filter );
211 return partition.search( searchContext );
212 }
213
214
215 /* (non-Javadoc)
216 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#getSchema(java.lang.String)
217 */
218 public Schema getSchema( String schemaName ) throws Exception
219 {
220 DN dn = new DN( "cn=" + schemaName + ",ou=schema" );
221 dn.normalize( schemaManager.getNormalizerMapping() );
222 return factory.getSchema( partition.lookup( new LookupOperationContext( null, dn ) ) );
223 }
224
225
226 /* (non-Javadoc)
227 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasMatchingRule(java.lang.String)
228 */
229 public boolean hasMatchingRule( String oid ) throws Exception
230 {
231 BranchNode filter = new AndNode();
232 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue(
233 MetaSchemaConstants.META_MATCHING_RULE_OC ) ) );
234
235 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) )
236 {
237 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) );
238 }
239 else
240 {
241 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) );
242 }
243
244 SearchControls searchControls = new SearchControls();
245 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
246 EntryFilteringCursor cursor = null;
247
248 try
249 {
250 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
251 filter, searchControls );
252 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
253
254 cursor = partition.search( searchOperationContext );
255
256 if ( !cursor.next() )
257 {
258 return false;
259 }
260
261 if ( cursor.next() )
262 {
263 throw new NamingException( I18n.err( I18n.ERR_430, oid ) );
264 }
265
266 return true;
267 }
268 finally
269 {
270 if ( cursor != null )
271 {
272 cursor.close();
273 }
274 }
275 }
276
277
278 /* (non-Javadoc)
279 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasAttributeType(java.lang.String)
280 */
281 public boolean hasAttributeType( String oid ) throws Exception
282 {
283 BranchNode filter = new AndNode();
284 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue(
285 MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC ) ) );
286
287 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) )
288 {
289 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) );
290 }
291 else
292 {
293 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) );
294 }
295
296 SearchControls searchControls = new SearchControls();
297 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
298 EntryFilteringCursor cursor = null;
299
300 try
301 {
302 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
303 filter, searchControls );
304 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
305
306 cursor = partition.search( searchOperationContext );
307
308 if ( !cursor.next() )
309 {
310 return false;
311 }
312
313 if ( cursor.next() )
314 {
315 throw new NamingException( I18n.err( I18n.ERR_431, oid ) );
316 }
317
318 return true;
319 }
320 finally
321 {
322 if ( cursor != null )
323 {
324 cursor.close();
325 }
326 }
327 }
328
329
330 /* (non-Javadoc)
331 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasObjectClass(java.lang.String)
332 */
333 public boolean hasObjectClass( String oid ) throws Exception
334 {
335 BranchNode filter = new AndNode();
336 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
337 new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC ) ) );
338
339 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) )
340 {
341 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) );
342 }
343 else
344 {
345 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) );
346 }
347
348 SearchControls searchControls = new SearchControls();
349 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
350 EntryFilteringCursor cursor = null;
351
352 try
353 {
354 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
355 filter, searchControls );
356 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
357
358 cursor = partition.search( searchOperationContext );
359
360 if ( !cursor.next() )
361 {
362 return false;
363 }
364
365 if ( cursor.next() )
366 {
367 throw new NamingException( I18n.err( I18n.ERR_431, oid ) );
368 }
369
370 return true;
371 }
372 finally
373 {
374 if ( cursor != null )
375 {
376 cursor.close();
377 }
378 }
379 }
380
381
382 /* (non-Javadoc)
383 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasSyntax(java.lang.String)
384 */
385 public boolean hasSyntax( String oid ) throws Exception
386 {
387 BranchNode filter = new AndNode();
388 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
389 new StringValue( MetaSchemaConstants.META_SYNTAX_OC ) ) );
390
391 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) )
392 {
393 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) );
394 }
395 else
396 {
397 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) );
398 }
399
400 SearchControls searchControls = new SearchControls();
401 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
402 EntryFilteringCursor cursor = null;
403
404 try
405 {
406 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
407 filter, searchControls );
408 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
409
410 cursor = partition.search( searchOperationContext );
411
412 if ( !cursor.next() )
413 {
414 return false;
415 }
416
417 if ( cursor.next() )
418 {
419 throw new NamingException( I18n.err( I18n.ERR_432, oid ) );
420 }
421
422 return true;
423 }
424 finally
425 {
426 if ( cursor != null )
427 {
428 cursor.close();
429 }
430 }
431 }
432
433
434 /* (non-Javadoc)
435 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#hasSyntaxChecker(java.lang.String)
436 */
437 public boolean hasSyntaxChecker( String oid ) throws Exception
438 {
439 BranchNode filter = new AndNode();
440 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
441 new StringValue( MetaSchemaConstants.META_SYNTAX_CHECKER_OC ) ) );
442
443 if ( NUMERIC_OID_CHECKER.isValidSyntax( oid ) )
444 {
445 filter.addNode( new EqualityNode<String>( M_OID_OID, new StringValue( oid ) ) );
446 }
447 else
448 {
449 filter.addNode( new EqualityNode<String>( M_NAME_OID, new StringValue( oid.toLowerCase() ) ) );
450 }
451
452 SearchControls searchControls = new SearchControls();
453 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
454 EntryFilteringCursor cursor = null;
455
456 try
457 {
458 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
459 filter, searchControls );
460 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
461
462 cursor = partition.search( searchOperationContext );
463
464 if ( !cursor.next() )
465 {
466 return false;
467 }
468
469 if ( cursor.next() )
470 {
471 throw new NamingException( I18n.err( I18n.ERR_433, oid ) );
472 }
473
474 return true;
475 }
476 finally
477 {
478 if ( cursor != null )
479 {
480 cursor.close();
481 }
482 }
483 }
484
485
486 /* (non-Javadoc)
487 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#findSchema(java.lang.String)
488 */
489 public String findSchema( String entityName ) throws Exception
490 {
491 DN dn = findDn( entityName );
492 if ( dn == null )
493 {
494 return null;
495 }
496
497 RDN rdn = dn.getRdn( 1 );
498
499 if ( !rdn.getNormType().equalsIgnoreCase( CN_OID ) )
500 {
501 throw new NamingException( I18n.err( I18n.ERR_434, dn.getNormName(), CN_OID, rdn.getNormType() ) );
502 }
503
504 return ( String ) rdn.getNormValue();
505 }
506
507
508 /* (non-Javadoc)
509 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#findDn(java.lang.String)
510 */
511 public DN findDn( String entityName ) throws Exception
512 {
513 ServerEntry sr = find( entityName );
514 DN dn = sr.getDn();
515 dn.normalize( schemaManager.getNormalizerMapping() );
516 return dn;
517 }
518
519
520 /* (non-Javadoc)
521 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#find(java.lang.String)
522 */
523 public ServerEntry find( String entityName ) throws Exception
524 {
525 BranchNode filter = new OrNode();
526 SimpleNode<String> nameAVA = new EqualityNode<String>( M_NAME_OID,
527 new StringValue( entityName.toLowerCase() ) );
528 SimpleNode<String> oidAVA = new EqualityNode<String>( M_OID_OID,
529 new StringValue( entityName.toLowerCase() ) );
530 filter.addNode( nameAVA );
531 filter.addNode( oidAVA );
532 SearchControls searchControls = new SearchControls();
533 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
534 EntryFilteringCursor cursor = null;
535
536 try
537 {
538 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
539 filter, searchControls );
540 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
541
542 cursor = partition.search( searchOperationContext );
543
544 if ( !cursor.next() )
545 {
546 return null;
547 }
548
549 ServerEntry sr = cursor.get();
550
551 if ( cursor.next() )
552 {
553 throw new NamingException( I18n.err( I18n.ERR_435, entityName ) );
554 }
555
556 return sr;
557 }
558 finally
559 {
560 if ( cursor != null )
561 {
562 cursor.close();
563 }
564 }
565 }
566
567
568 /* (non-Javadoc)
569 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#enableSchema(java.lang.String)
570 */
571 public void enableSchema( String schemaName ) throws Exception
572 {
573 DN dn = new DN( "cn=" + schemaName + ",ou=schema" );
574 dn.normalize( schemaManager.getNormalizerMapping() );
575 ServerEntry entry = partition.lookup( new LookupOperationContext( null, dn ) );
576 EntryAttribute disabledAttr = entry.get( disabledAttributeType );
577 List<Modification> mods = new ArrayList<Modification>( 3 );
578
579 if ( disabledAttr == null )
580 {
581 LOG.warn( "Does not make sense: you're trying to enable {} schema which is already enabled", schemaName );
582 return;
583 }
584
585 boolean isDisabled = disabledAttr.contains( "TRUE" );
586
587 if ( !isDisabled )
588 {
589 LOG.warn( "Does not make sense: you're trying to enable {} schema which is already enabled", schemaName );
590 return;
591 }
592
593 mods.add( new ServerModification( ModificationOperation.REMOVE_ATTRIBUTE, new DefaultServerAttribute(
594 MetaSchemaConstants.M_DISABLED_AT, schemaManager.lookupAttributeTypeRegistry( MetaSchemaConstants.M_DISABLED_AT ) ) ) );
595
596 mods.add( new ServerModification( ModificationOperation.ADD_ATTRIBUTE, new DefaultServerAttribute(
597 SchemaConstants.MODIFIERS_NAME_AT, schemaManager.lookupAttributeTypeRegistry( SchemaConstants.MODIFIERS_NAME_AT ),
598 ServerDNConstants.ADMIN_SYSTEM_DN ) ) );
599
600 mods.add( new ServerModification( ModificationOperation.ADD_ATTRIBUTE, new DefaultServerAttribute(
601 SchemaConstants.MODIFY_TIMESTAMP_AT, schemaManager.lookupAttributeTypeRegistry( SchemaConstants.MODIFY_TIMESTAMP_AT ), DateUtils
602 .getGeneralizedTime() ) ) );
603
604 partition.modify( new ModifyOperationContext( null, dn, mods ) );
605 }
606
607
608 /* (non-Javadoc)
609 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listSyntaxDependents(java.lang.String)
610 */
611 public Set<ServerEntry> listSyntaxDependents( String numericOid ) throws Exception
612 {
613 Set<ServerEntry> set = new HashSet<ServerEntry>();
614 BranchNode filter = new AndNode();
615
616 // subfilter for (| (objectClass=metaMatchingRule) (objectClass=metaAttributeType))
617 BranchNode or = new OrNode();
618 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
619 new StringValue( MetaSchemaConstants.META_MATCHING_RULE_OC.toLowerCase() ) ) );
620 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
621 new StringValue( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) );
622
623 filter.addNode( or );
624 filter.addNode( new EqualityNode<String>( M_SYNTAX_OID, new StringValue( numericOid.toLowerCase() ) ) );
625
626 SearchControls searchControls = new SearchControls();
627 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
628 EntryFilteringCursor cursor = null;
629
630 try
631 {
632 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
633 filter, searchControls );
634 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
635
636 cursor = partition.search( searchOperationContext );
637
638 while ( cursor.next() )
639 {
640 set.add( cursor.get() );
641 }
642 }
643 finally
644 {
645 if ( cursor != null )
646 {
647 cursor.close();
648 }
649 }
650
651 return set;
652 }
653
654
655 /* (non-Javadoc)
656 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listMatchingRuleDependents(org.apache.directory.shared.ldap.schema.MatchingRule)
657 */
658 public Set<ServerEntry> listMatchingRuleDependents( MatchingRule mr ) throws Exception
659 {
660 Set<ServerEntry> set = new HashSet<ServerEntry>();
661 BranchNode filter = new AndNode();
662
663 // ( objectClass = metaAttributeType )
664 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue(
665 MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) );
666
667 BranchNode or = new OrNode();
668 or.addNode( new EqualityNode<String>( M_ORDERING_OID, new StringValue( mr.getOid() ) ) );
669 or.addNode( new EqualityNode<String>( M_SUBSTRING_OID, new StringValue( mr.getOid() ) ) );
670 or.addNode( new EqualityNode<String>( M_EQUALITY_OID, new StringValue( mr.getOid() ) ) );
671 filter.addNode( or );
672
673 List<String> names = mr.getNames();
674
675 if ( ( names != null ) && ( names.size() > 0 ) )
676 {
677 for ( String name : names )
678 {
679 or.addNode( new EqualityNode<String>( M_ORDERING_OID, new StringValue( name.toLowerCase() ) ) );
680 or.addNode( new EqualityNode<String>( M_SUBSTRING_OID, new StringValue( name.toLowerCase() ) ) );
681 or.addNode( new EqualityNode<String>( M_EQUALITY_OID, new StringValue( name.toLowerCase() ) ) );
682 }
683 }
684
685 SearchControls searchControls = new SearchControls();
686 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
687 EntryFilteringCursor cursor = null;
688
689 try
690 {
691 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
692 filter, searchControls );
693 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
694
695 cursor = partition.search( searchOperationContext );
696
697 while ( cursor.next() )
698 {
699 set.add( cursor.get() );
700 }
701 }
702 finally
703 {
704 if ( cursor != null )
705 {
706 cursor.close();
707 }
708 }
709
710 return set;
711 }
712
713
714 /* (non-Javadoc)
715 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listAllNames()
716 */
717 public EntryFilteringCursor listAllNames() throws Exception
718 {
719 SearchControls searchControls = new SearchControls();
720 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
721 BranchNode filter = new AndNode();
722
723 // (& (m-oid=*) (m-name=*) )
724 filter.addNode( new PresenceNode( M_OID_OID ) );
725 filter.addNode( new PresenceNode( M_NAME_OID ) );
726
727 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
728 filter, searchControls );
729 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
730
731 return partition.search( searchOperationContext );
732 }
733
734
735 /* (non-Javadoc)
736 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listAttributeTypeDependents(org.apache.directory.shared.ldap.schema.AttributeType)
737 */
738 public Set<ServerEntry> listAttributeTypeDependents( AttributeType at ) throws Exception
739 {
740 /*
741 * Right now the following inefficient filter is being used:
742 *
743 * ( &
744 * ( | ( objectClass = metaAttributeType ) ( objectClass = metaObjectClass ) )
745 * ( | ( m-oid = $oid ) ( m-must = $oid ) ( m-supAttributeType = $oid ) )
746 * )
747 *
748 * the reason why this is inefficient is because the or terms have large scan counts
749 * and several loops are going to be required. The following search is better because
750 * it constrains the results better:
751 *
752 * ( |
753 * ( & ( objectClass = metaAttributeType ) ( m-supAttributeType = $oid ) )
754 * ( & ( objectClass = metaObjectClass ) ( | ( m-may = $oid ) ( m-must = $oid ) ) )
755 * )
756 */
757
758 Set<ServerEntry> set = new HashSet<ServerEntry>();
759 BranchNode filter = new AndNode();
760
761 // ( objectClass = metaAttributeType )
762 BranchNode or = new OrNode();
763 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
764 new StringValue( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC.toLowerCase() ) ) );
765 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
766 new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC.toLowerCase() ) ) );
767 filter.addNode( or );
768
769 or = new OrNode();
770 or.addNode( new EqualityNode<String>( M_MAY_OID, new StringValue( at.getOid() ) ) );
771 or.addNode( new EqualityNode<String>( M_MUST_OID, new StringValue( at.getOid() ) ) );
772 or.addNode( new EqualityNode<String>( M_SUP_ATTRIBUTE_TYPE_OID, new StringValue( at.getOid() ) ) );
773 filter.addNode( or );
774
775 SearchControls searchControls = new SearchControls();
776 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
777 EntryFilteringCursor cursor = null;
778
779 try
780 {
781 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
782 filter, searchControls );
783 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
784
785 cursor = partition.search( searchOperationContext );
786
787 while ( cursor.next() )
788 {
789 set.add( cursor.get() );
790 }
791 }
792 finally
793 {
794 if ( cursor != null )
795 {
796 cursor.close();
797 }
798 }
799
800 return set;
801 }
802
803
804 /* (non-Javadoc)
805 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listSchemaDependents(java.lang.String)
806 */
807 public Set<ServerEntry> listSchemaDependents( String schemaName ) throws Exception
808 {
809 /*
810 * The following filter is being used:
811 *
812 * ( & ( objectClass = metaSchema ) ( m-dependencies = $schemaName ) )
813 */
814
815 Set<ServerEntry> set = new HashSet<ServerEntry>();
816 BranchNode filter = new AndNode();
817
818 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID,
819 new StringValue( MetaSchemaConstants.META_SCHEMA_OC.toLowerCase() ) ) );
820 filter.addNode( new EqualityNode<String>( M_DEPENDENCIES_OID,
821 new StringValue( schemaName.toLowerCase() ) ) );
822
823 SearchControls searchControls = new SearchControls();
824 searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
825 EntryFilteringCursor cursor = null;
826
827 try
828 {
829 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
830 filter, searchControls );
831 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
832
833 cursor = partition.search( searchOperationContext );
834
835 while ( cursor.next() )
836 {
837 set.add( cursor.get() );
838 }
839 }
840 finally
841 {
842 if ( cursor != null )
843 {
844 cursor.close();
845 }
846 }
847
848 return set;
849 }
850
851
852 /* (non-Javadoc)
853 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listEnabledSchemaDependents(java.lang.String)
854 */
855 public Set<ServerEntry> listEnabledSchemaDependents( String schemaName ) throws Exception
856 {
857 Set<ServerEntry> set = new HashSet<ServerEntry>();
858 BranchNode filter = new AndNode();
859
860 filter.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue(
861 MetaSchemaConstants.META_SCHEMA_OC.toLowerCase() ) ) );
862 filter.addNode( new EqualityNode<String>( M_DEPENDENCIES_OID, new StringValue(
863 schemaName.toLowerCase() ) ) );
864
865 SearchControls searchControls = new SearchControls();
866 searchControls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
867 EntryFilteringCursor cursor = null;
868
869 try
870 {
871 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
872 filter, searchControls );
873 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
874
875 cursor = partition.search( searchOperationContext );
876
877 while ( cursor.next() )
878 {
879 ServerEntry sr = cursor.get();
880 EntryAttribute disabled = sr.get( disabledAttributeType );
881
882 if ( disabled == null )
883 {
884 set.add( sr );
885 }
886 else if ( disabled.get().equals( "FALSE" ) )
887 {
888 set.add( sr );
889 }
890 }
891 }
892 finally
893 {
894 if ( cursor != null )
895 {
896 cursor.close();
897 }
898 }
899
900 return set;
901 }
902
903
904 /* (non-Javadoc)
905 * @see org.apache.directory.server.core.schema.SchemaPartitionDao#listObjectClassDependents(org.apache.directory.shared.ldap.schema.ObjectClass)
906 */
907 public Set<ServerEntry> listObjectClassDependents( ObjectClass oc ) throws Exception
908 {
909 /*
910 * Right now the following inefficient filter is being used:
911 *
912 * ( &
913 * ( | ( objectClass = metaObjectClass ) ( objectClass = metaDITContentRule )
914 * ( objectClass = metaNameForm ) )
915 * ( | ( m-oc = $oid ) ( m-aux = $oid ) ( m-supObjectClass = $oid ) )
916 * )
917 *
918 * The reason why this is inefficient is because the or terms have large scan counts
919 * and several loops are going to be required. For example all the objectClasses and
920 * all the metaDITContentRules and all the metaNameForm candidates will be a massive
921 * number. This is probably going to be bigger than the 2nd term where a candidate
922 * satisfies one of the terms.
923 *
924 * The following search is better because it constrains the results better:
925 *
926 * ( |
927 * ( & ( objectClass = metaNameForm ) ( m-oc = $oid ) )
928 * ( & ( objectClass = metaObjectClass ) ( m-supObjectClass = $oid ) )
929 * ( & ( objectClass = metaDITContentRule ) ( m-aux = $oid ) )
930 * )
931 */
932
933 Set<ServerEntry> set = new HashSet<ServerEntry>();
934 BranchNode filter = new AndNode();
935
936 BranchNode or = new OrNode();
937 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( MetaSchemaConstants.META_NAME_FORM_OC
938 .toLowerCase() ) ) );
939 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue( MetaSchemaConstants.META_OBJECT_CLASS_OC
940 .toLowerCase() ) ) );
941 or.addNode( new EqualityNode<String>( OBJECTCLASS_OID, new StringValue(
942 MetaSchemaConstants.META_DIT_CONTENT_RULE_OC.toLowerCase() ) ) );
943 filter.addNode( or );
944
945 or = new OrNode();
946 or.addNode( new EqualityNode<String>( M_AUX_OID, new StringValue( oc.getOid() ) ) );
947 or.addNode( new EqualityNode<String>( M_OC_OID, new StringValue( oc.getOid() ) ) );
948 or.addNode( new EqualityNode<String>( M_SUP_OBJECT_CLASS_OID, new StringValue( oc.getOid() ) ) );
949 filter.addNode( or );
950
951 SearchControls searchControls = new SearchControls();
952 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
953 EntryFilteringCursor cursor = null;
954
955 try
956 {
957 SearchOperationContext searchOperationContext = new SearchOperationContext( null, partition.getSuffixDn(),
958 filter, searchControls );
959 searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
960
961 cursor = partition.search( searchOperationContext );
962
963 while ( cursor.next() )
964 {
965 set.add( cursor.get() );
966 }
967 }
968 finally
969 {
970 if ( cursor != null )
971 {
972 cursor.close();
973 }
974 }
975
976 return set;
977 }
978 }