1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.schema.registries;
21
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.directory.api.i18n.I18n;
32 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
33 import org.apache.directory.api.ldap.model.exception.LdapException;
34 import org.apache.directory.api.ldap.model.exception.LdapProtocolErrorException;
35 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
36 import org.apache.directory.api.ldap.model.exception.LdapSchemaExceptionCodes;
37 import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
38 import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
39 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
40 import org.apache.directory.api.ldap.model.schema.AttributeType;
41 import org.apache.directory.api.ldap.model.schema.DitContentRule;
42 import org.apache.directory.api.ldap.model.schema.DitStructureRule;
43 import org.apache.directory.api.ldap.model.schema.LdapComparator;
44 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
45 import org.apache.directory.api.ldap.model.schema.LoadableSchemaObject;
46 import org.apache.directory.api.ldap.model.schema.MatchingRule;
47 import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
48 import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
49 import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
50 import org.apache.directory.api.ldap.model.schema.NameForm;
51 import org.apache.directory.api.ldap.model.schema.Normalizer;
52 import org.apache.directory.api.ldap.model.schema.ObjectClass;
53 import org.apache.directory.api.ldap.model.schema.SchemaObject;
54 import org.apache.directory.api.ldap.model.schema.SchemaObjectWrapper;
55 import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
56 import org.apache.directory.api.ldap.model.schema.registries.helper.AttributeTypeHelper;
57 import org.apache.directory.api.ldap.model.schema.registries.helper.DitContentRuleHelper;
58 import org.apache.directory.api.ldap.model.schema.registries.helper.DitStructureRuleHelper;
59 import org.apache.directory.api.ldap.model.schema.registries.helper.LdapSyntaxHelper;
60 import org.apache.directory.api.ldap.model.schema.registries.helper.MatchingRuleHelper;
61 import org.apache.directory.api.ldap.model.schema.registries.helper.MatchingRuleUseHelper;
62 import org.apache.directory.api.ldap.model.schema.registries.helper.NameFormHelper;
63 import org.apache.directory.api.ldap.model.schema.registries.helper.ObjectClassHelper;
64 import org.apache.directory.api.util.Strings;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68
69
70
71
72
73
74 public class Registries implements SchemaLoaderListener, Cloneable
75 {
76
77 private static final Logger LOG = LoggerFactory.getLogger( Registries.class );
78
79
80
81
82
83 protected Map<String, Schema> loadedSchemas = new HashMap<String, Schema>();
84
85
86 protected AttributeTypeRegistry attributeTypeRegistry;
87
88
89 protected ObjectClassRegistry objectClassRegistry;
90
91
92 protected ComparatorRegistry comparatorRegistry;
93
94
95 protected DitContentRuleRegistry ditContentRuleRegistry;
96
97
98 protected DitStructureRuleRegistry ditStructureRuleRegistry;
99
100
101 protected MatchingRuleRegistry matchingRuleRegistry;
102
103
104 protected MatchingRuleUseRegistry matchingRuleUseRegistry;
105
106
107 protected NameFormRegistry nameFormRegistry;
108
109
110 protected NormalizerRegistry normalizerRegistry;
111
112
113 protected OidRegistry<SchemaObject> globalOidRegistry;
114
115
116 protected SyntaxCheckerRegistry syntaxCheckerRegistry;
117
118
119 protected LdapSyntaxRegistry ldapSyntaxRegistry;
120
121
122 private Map<String, Set<SchemaObjectWrapper>> schemaObjects;
123
124
125 private boolean isRelaxed;
126
127
128 private boolean disabledAccepted;
129
130
131 public static final boolean STRICT = false;
132 public static final boolean RELAXED = true;
133
134
135
136
137
138 protected Map<SchemaObjectWrapper, Set<SchemaObjectWrapper>> usedBy;
139
140
141
142
143
144 protected Map<SchemaObjectWrapper, Set<SchemaObjectWrapper>> using;
145
146
147
148
149
150 public Registries()
151 {
152 globalOidRegistry = new OidRegistry<SchemaObject>();
153 attributeTypeRegistry = new DefaultAttributeTypeRegistry();
154 comparatorRegistry = new DefaultComparatorRegistry();
155 ditContentRuleRegistry = new DefaultDitContentRuleRegistry();
156 ditStructureRuleRegistry = new DefaultDitStructureRuleRegistry();
157 ldapSyntaxRegistry = new DefaultLdapSyntaxRegistry();
158 matchingRuleRegistry = new DefaultMatchingRuleRegistry();
159 matchingRuleUseRegistry = new DefaultMatchingRuleUseRegistry();
160 nameFormRegistry = new DefaultNameFormRegistry();
161 normalizerRegistry = new DefaultNormalizerRegistry();
162 objectClassRegistry = new DefaultObjectClassRegistry();
163 syntaxCheckerRegistry = new DefaultSyntaxCheckerRegistry();
164 schemaObjects = new HashMap<String, Set<SchemaObjectWrapper>>();
165 usedBy = new HashMap<SchemaObjectWrapper, Set<SchemaObjectWrapper>>();
166 using = new HashMap<SchemaObjectWrapper, Set<SchemaObjectWrapper>>();
167
168 isRelaxed = STRICT;
169 disabledAccepted = false;
170 }
171
172
173
174
175
176 public AttributeTypeRegistry getAttributeTypeRegistry()
177 {
178 return attributeTypeRegistry;
179 }
180
181
182
183
184
185 public ComparatorRegistry getComparatorRegistry()
186 {
187 return comparatorRegistry;
188 }
189
190
191
192
193
194 public DitContentRuleRegistry getDitContentRuleRegistry()
195 {
196 return ditContentRuleRegistry;
197 }
198
199
200
201
202
203 public DitStructureRuleRegistry getDitStructureRuleRegistry()
204 {
205 return ditStructureRuleRegistry;
206 }
207
208
209
210
211
212 public MatchingRuleRegistry getMatchingRuleRegistry()
213 {
214 return matchingRuleRegistry;
215 }
216
217
218
219
220
221 public MatchingRuleUseRegistry getMatchingRuleUseRegistry()
222 {
223 return matchingRuleUseRegistry;
224 }
225
226
227
228
229
230 public NameFormRegistry getNameFormRegistry()
231 {
232 return nameFormRegistry;
233 }
234
235
236
237
238
239 public NormalizerRegistry getNormalizerRegistry()
240 {
241 return normalizerRegistry;
242 }
243
244
245
246
247
248 public ObjectClassRegistry getObjectClassRegistry()
249 {
250 return objectClassRegistry;
251 }
252
253
254
255
256
257 public OidRegistry<SchemaObject> getGlobalOidRegistry()
258 {
259 return globalOidRegistry;
260 }
261
262
263
264
265
266 public SyntaxCheckerRegistry getSyntaxCheckerRegistry()
267 {
268 return syntaxCheckerRegistry;
269 }
270
271
272
273
274
275 public LdapSyntaxRegistry getLdapSyntaxRegistry()
276 {
277 return ldapSyntaxRegistry;
278 }
279
280
281
282
283
284
285
286
287
288 public String getOid( String name )
289 {
290
291
292 try
293 {
294 AttributeType attributeType = attributeTypeRegistry.lookup( name );
295
296 if ( attributeType != null )
297 {
298 return attributeType.getOid();
299 }
300 }
301 catch ( LdapException ne )
302 {
303
304 }
305
306
307 try
308 {
309 ObjectClass objectClass = objectClassRegistry.lookup( name );
310
311 if ( objectClass != null )
312 {
313 return objectClass.getOid();
314 }
315 }
316 catch ( LdapException ne )
317 {
318
319 }
320
321
322 try
323 {
324 LdapSyntax ldapSyntax = ldapSyntaxRegistry.lookup( name );
325
326 if ( ldapSyntax != null )
327 {
328 return ldapSyntax.getOid();
329 }
330 }
331 catch ( LdapException ne )
332 {
333
334 }
335
336
337 try
338 {
339 MatchingRule matchingRule = matchingRuleRegistry.lookup( name );
340
341 if ( matchingRule != null )
342 {
343 return matchingRule.getOid();
344 }
345 }
346 catch ( LdapException ne )
347 {
348
349 }
350
351
352 try
353 {
354 MatchingRuleUse matchingRuleUse = matchingRuleUseRegistry.lookup( name );
355
356 if ( matchingRuleUse != null )
357 {
358 return matchingRuleUse.getOid();
359 }
360 }
361 catch ( LdapException ne )
362 {
363
364 }
365
366
367 try
368 {
369 NameForm nameForm = nameFormRegistry.lookup( name );
370
371 if ( nameForm != null )
372 {
373 return nameForm.getOid();
374 }
375 }
376 catch ( LdapException ne )
377 {
378
379 }
380
381
382 try
383 {
384 DitContentRule ditContentRule = ditContentRuleRegistry.lookup( name );
385
386 if ( ditContentRule != null )
387 {
388 return ditContentRule.getOid();
389 }
390 }
391 catch ( LdapException ne )
392 {
393
394 }
395
396
397 try
398 {
399 DitStructureRule ditStructureRule = ditStructureRuleRegistry.lookup( name );
400
401 if ( ditStructureRule != null )
402 {
403 return ditStructureRule.getOid();
404 }
405 }
406 catch ( LdapException ne )
407 {
408
409 }
410
411 return null;
412 }
413
414
415
416
417
418
419
420
421 public Schema getLoadedSchema( String schemaName )
422 {
423 return loadedSchemas.get( Strings.toLowerCase( schemaName ) );
424 }
425
426
427
428
429
430
431
432
433 public boolean isSchemaLoaded( String schemaName )
434 {
435 return loadedSchemas.containsKey( Strings.toLowerCase( schemaName ) );
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 public List<Throwable> checkRefInteg()
462 {
463 ArrayList<Throwable> errors = new ArrayList<Throwable>();
464
465
466
467
468
469 for ( Normalizer normalizer : normalizerRegistry )
470 {
471 resolve( normalizer, errors );
472 }
473
474
475 for ( LdapComparator<?> comparator : comparatorRegistry )
476 {
477 resolve( comparator, errors );
478 }
479
480
481 for ( SyntaxChecker syntaxChecker : syntaxCheckerRegistry )
482 {
483 resolve( syntaxChecker, errors );
484 }
485
486
487
488 for ( LdapSyntax ldapSyntax : ldapSyntaxRegistry )
489 {
490 resolve( ldapSyntax, errors );
491 }
492
493
494
495 for ( MatchingRule matchingRule : matchingRuleRegistry )
496 {
497 resolve( matchingRule, errors );
498 }
499
500
501
502 for ( AttributeType attributeType : attributeTypeRegistry )
503 {
504 resolve( attributeType, errors );
505 }
506
507
508
509 for ( ObjectClass objectClass : objectClassRegistry )
510 {
511 resolve( objectClass, errors );
512 }
513
514
515 return errors;
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 public void delCrossReferences( AttributeType attributeType )
537 {
538 if ( attributeType.getEquality() != null )
539 {
540 delReference( attributeType, attributeType.getEquality() );
541 }
542
543 if ( attributeType.getOrdering() != null )
544 {
545 delReference( attributeType, attributeType.getOrdering() );
546 }
547
548 if ( attributeType.getSubstring() != null )
549 {
550 delReference( attributeType, attributeType.getSubstring() );
551 }
552
553 if ( attributeType.getSyntax() != null )
554 {
555 delReference( attributeType, attributeType.getSyntax() );
556 }
557
558 if ( attributeType.getSuperior() != null )
559 {
560 delReference( attributeType, attributeType.getSuperior() );
561 }
562 }
563
564
565
566
567
568
569
570
571
572
573
574
575 private void buildAttributeTypeReferences( List<Throwable> errors )
576 {
577 for ( AttributeType attributeType : attributeTypeRegistry )
578 {
579 if ( ( getUsing( attributeType ) == null ) || getUsing( attributeType ).isEmpty() )
580 {
581 buildReference( errors, attributeType );
582 }
583 }
584 }
585
586
587
588
589
590 private void buildComparatorReferences( List<Throwable> errors )
591 {
592 for ( LdapComparator<?> comparator : comparatorRegistry )
593 {
594 buildReference( errors, comparator );
595 }
596 }
597
598
599
600
601
602 private void buildDitContentRuleReferences( List<Throwable> errors )
603 {
604 for ( @SuppressWarnings("unused")
605 DitContentRule ditContentRule : ditContentRuleRegistry )
606 {
607
608 }
609 }
610
611
612
613
614
615 private void buildDitStructureRuleReferences( List<Throwable> errors )
616 {
617 for ( @SuppressWarnings("unused")
618 DitStructureRule ditStructureRule : ditStructureRuleRegistry )
619 {
620
621 }
622 }
623
624
625
626
627
628
629
630
631 public void delCrossReferences( MatchingRule matchingRule )
632 {
633 if ( matchingRule.getLdapComparator() != null )
634 {
635 delReference( matchingRule, matchingRule.getLdapComparator() );
636 }
637
638 if ( matchingRule.getNormalizer() != null )
639 {
640 delReference( matchingRule, matchingRule.getNormalizer() );
641 }
642
643 if ( matchingRule.getSyntax() != null )
644 {
645 delReference( matchingRule, matchingRule.getSyntax() );
646 }
647 }
648
649
650
651
652
653 public void buildReference( List<Throwable> errors, SchemaObject schemaObject )
654 {
655 try
656 {
657 switch ( schemaObject.getObjectType() )
658 {
659 case ATTRIBUTE_TYPE:
660 AttributeTypeHelper.addToRegistries( ( MutableAttributeType ) schemaObject, errors, this );
661 break;
662
663 case DIT_CONTENT_RULE:
664 DitContentRuleHelper.addToRegistries( ( DitContentRule ) schemaObject, errors, this );
665 break;
666
667 case DIT_STRUCTURE_RULE:
668 DitStructureRuleHelper.addToRegistries( ( DitStructureRule ) schemaObject, errors, this );
669 break;
670
671 case LDAP_SYNTAX:
672 LdapSyntaxHelper.addToRegistries( ( LdapSyntax ) schemaObject, errors, this );
673 break;
674
675 case MATCHING_RULE:
676 MatchingRuleHelper.addToRegistries( ( MutableMatchingRule ) schemaObject, errors, this );
677 break;
678
679 case MATCHING_RULE_USE:
680 MatchingRuleUseHelper.addToRegistries( ( MatchingRuleUse ) schemaObject, errors, this );
681 break;
682
683 case NAME_FORM:
684 NameFormHelper.addToRegistries( ( NameForm ) schemaObject, errors, this );
685 break;
686
687 case OBJECT_CLASS:
688 ObjectClassHelper.addToRegistries( ( ObjectClass ) schemaObject, errors, this );
689 break;
690 }
691 }
692 catch ( LdapException ne )
693 {
694
695 String msg = I18n.err( I18n.ERR_04292, schemaObject.getName(), ne.getLocalizedMessage() );
696
697 Throwable error = new LdapProtocolErrorException( msg, ne );
698 errors.add( error );
699 LOG.info( msg );
700 }
701 }
702
703
704
705
706
707 public void removeReference( List<Throwable> errors, SchemaObject schemaObject )
708 {
709 try
710 {
711 switch ( schemaObject.getObjectType() )
712 {
713 case ATTRIBUTE_TYPE:
714 AttributeTypeHelper.removeFromRegistries( ( AttributeType ) schemaObject, errors, this );
715 break;
716
717 case LDAP_SYNTAX:
718 LdapSyntaxHelper.removeFromRegistries( ( LdapSyntax ) schemaObject, errors, this );
719 break;
720
721 case MATCHING_RULE:
722 MatchingRuleHelper.removeFromRegistries( ( MatchingRule ) schemaObject, errors, this );
723 break;
724
725 case OBJECT_CLASS:
726 ObjectClassHelper.removeFromRegistries( ( ObjectClass ) schemaObject, errors, this );
727 break;
728
729 case DIT_CONTENT_RULE :
730
731 break;
732
733 case DIT_STRUCTURE_RULE :
734
735 break;
736
737 case NAME_FORM :
738
739 break;
740
741 case MATCHING_RULE_USE :
742
743 break;
744 }
745 }
746 catch ( LdapException ne )
747 {
748
749 String msg = I18n.err( I18n.ERR_04293, schemaObject.getName(), ne.getLocalizedMessage() );
750
751 Throwable error = new LdapSchemaViolationException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg, ne );
752 errors.add( error );
753 LOG.info( msg );
754 }
755 }
756
757
758
759
760
761 private void buildMatchingRuleReferences( List<Throwable> errors )
762 {
763 for ( MatchingRule matchingRule : matchingRuleRegistry )
764 {
765 buildReference( errors, matchingRule );
766 }
767 }
768
769
770
771
772
773 private void buildMatchingRuleUseReferences( List<Throwable> errors )
774 {
775 for ( MatchingRuleUse matchingRuleUse : matchingRuleUseRegistry )
776 {
777 buildReference( errors, matchingRuleUse );
778 }
779 }
780
781
782
783
784
785 private void buildNameFormReferences( List<Throwable> errors )
786 {
787 for ( @SuppressWarnings("unused")
788 NameForm nameFormRule : nameFormRegistry )
789 {
790
791 }
792 }
793
794
795
796
797
798 private void buildNormalizerReferences( List<Throwable> errors )
799 {
800 for ( Normalizer normalizer : normalizerRegistry )
801 {
802 buildReference( errors, normalizer );
803 }
804 }
805
806
807
808
809
810 private void buildObjectClassReferences( List<Throwable> errors )
811 {
812
813 Set<String> done = new HashSet<String>();
814
815
816 for ( ObjectClass objectClass : objectClassRegistry )
817 {
818 if ( done.contains( objectClass.getOid() ) )
819 {
820 continue;
821 }
822 else
823 {
824 done.add( objectClass.getOid() );
825 }
826
827 buildReference( errors, objectClass );
828 }
829 }
830
831
832
833
834
835 private void buildLdapSyntaxReferences( List<Throwable> errors )
836 {
837 for ( LdapSyntax syntax : ldapSyntaxRegistry )
838 {
839 buildReference( errors, syntax );
840 }
841 }
842
843
844
845
846
847 private void buildSyntaxCheckerReferences( List<Throwable> errors )
848 {
849 for ( SyntaxChecker syntaxChecker : syntaxCheckerRegistry )
850 {
851 buildReference( errors, syntaxChecker );
852 }
853 }
854
855
856
857
858
859
860
861 public List<Throwable> buildReferences()
862 {
863 List<Throwable> errors = new ArrayList<Throwable>();
864
865
866 buildComparatorReferences( errors );
867
868
869 buildNormalizerReferences( errors );
870
871
872 buildSyntaxCheckerReferences( errors );
873
874
875 buildLdapSyntaxReferences( errors );
876
877
878 buildMatchingRuleReferences( errors );
879
880
881 buildAttributeTypeReferences( errors );
882
883
884 buildMatchingRuleUseReferences( errors );
885
886
887 buildObjectClassReferences( errors );
888
889
890 buildDitContentRuleReferences( errors );
891
892
893 buildNameFormReferences( errors );
894
895
896 buildDitStructureRuleReferences( errors );
897
898 return errors;
899 }
900
901
902
903
904
905
906
907
908 private void resolve( LdapSyntax syntax, List<Throwable> errors )
909 {
910
911
912 try
913 {
914 LdapSyntaxHelper.addToRegistries( syntax, errors, this );
915 }
916 catch ( LdapException e )
917 {
918 errors.add( e );
919 }
920 }
921
922
923
924
925
926
927
928
929 private void resolve( Normalizer normalizer, List<Throwable> errors )
930 {
931
932 }
933
934
935
936
937
938
939
940
941 private void resolve( LdapComparator<?> comparator, List<Throwable> errors )
942 {
943
944 }
945
946
947
948
949
950
951
952
953 private void resolve( SyntaxChecker syntaxChecker, List<Throwable> errors )
954 {
955
956 }
957
958
959
960
961
962
963 private void resolve( MatchingRule matchingRule, List<Throwable> errors )
964 {
965
966 String syntaxOid = matchingRule.getSyntaxOid();
967
968 if ( syntaxOid != null )
969 {
970
971 try
972 {
973 ldapSyntaxRegistry.lookup( syntaxOid );
974 }
975 catch ( LdapException ne )
976 {
977
978 LdapSchemaException ldapSchemaException = new LdapSchemaException(
979 LdapSchemaExceptionCodes.OID_ALREADY_REGISTERED, I18n.err( I18n.ERR_04294, matchingRule.getOid() ),
980 ne );
981 ldapSchemaException.setSourceObject( matchingRule );
982 errors.add( ldapSchemaException );
983 }
984 }
985 else
986 {
987
988 LdapSchemaException ldapSchemaException = new LdapSchemaException(
989 LdapSchemaExceptionCodes.OID_ALREADY_REGISTERED, I18n.err( I18n.ERR_04294, matchingRule.getOid() ) );
990 ldapSchemaException.setSourceObject( matchingRule );
991 errors.add( ldapSchemaException );
992 }
993
994
995 Normalizer normalizer = matchingRule.getNormalizer();
996
997 if ( normalizer == null )
998 {
999
1000 Throwable error = new LdapSchemaViolationException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err(
1001 I18n.ERR_04295, matchingRule.getOid() ) );
1002 errors.add( error );
1003 }
1004
1005
1006 LdapComparator<?> comparator = matchingRule.getLdapComparator();
1007
1008 if ( comparator == null )
1009 {
1010
1011 Throwable error = new LdapSchemaViolationException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err(
1012 I18n.ERR_04296, matchingRule.getOid() ) );
1013 errors.add( error );
1014 }
1015 }
1016
1017
1018
1019
1020
1021 private void resolveRecursive( AttributeType attributeType, Set<String> processed, List<Throwable> errors )
1022 {
1023
1024 String superiorOid = attributeType.getSuperiorOid();
1025
1026 AttributeType superior = null;
1027
1028 if ( superiorOid != null )
1029 {
1030
1031 try
1032 {
1033 superior = attributeTypeRegistry.lookup( superiorOid );
1034 }
1035 catch ( LdapException ne )
1036 {
1037
1038 if ( !processed.contains( superiorOid ) )
1039 {
1040 errors.add( ne );
1041 }
1042 }
1043
1044
1045
1046 if ( superior != null )
1047 {
1048 if ( !processed.contains( superiorOid ) )
1049 {
1050 resolveRecursive( superior, processed, errors );
1051 processed.add( attributeType.getOid() );
1052 }
1053 else
1054 {
1055
1056 Throwable error = new LdapSchemaViolationException( ResultCodeEnum.OTHER, I18n.err( I18n.ERR_04297,
1057 attributeType.getOid() ) );
1058 errors.add( error );
1059 return;
1060 }
1061 }
1062 }
1063
1064
1065
1066 String syntaxOid = attributeType.getSyntaxOid();
1067
1068 if ( syntaxOid != null )
1069 {
1070
1071 try
1072 {
1073 ldapSyntaxRegistry.lookup( syntaxOid );
1074 }
1075 catch ( LdapException ne )
1076 {
1077
1078 errors.add( ne );
1079 }
1080 }
1081 else
1082 {
1083
1084 if ( superior == null )
1085 {
1086
1087
1088 Throwable error = new LdapSchemaViolationException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, I18n.err(
1089 I18n.ERR_04298, attributeType.getOid() ) );
1090 errors.add( error );
1091 }
1092 }
1093
1094
1095
1096 String equalityOid = attributeType.getEqualityOid();
1097
1098 if ( equalityOid != null )
1099 {
1100
1101 try
1102 {
1103 matchingRuleRegistry.lookup( equalityOid );
1104 }
1105 catch ( LdapException ne )
1106 {
1107
1108 errors.add( ne );
1109 }
1110 }
1111
1112
1113
1114 String orderingOid = attributeType.getOrderingOid();
1115
1116 if ( orderingOid != null )
1117 {
1118
1119 try
1120 {
1121 matchingRuleRegistry.lookup( orderingOid );
1122 }
1123 catch ( LdapException ne )
1124 {
1125
1126 errors.add( ne );
1127 }
1128 }
1129
1130
1131
1132 String substringOid = attributeType.getSubstringOid();
1133
1134 if ( substringOid != null )
1135 {
1136
1137 try
1138 {
1139 matchingRuleRegistry.lookup( substringOid );
1140 }
1141 catch ( LdapException ne )
1142 {
1143
1144 errors.add( ne );
1145 }
1146 }
1147 }
1148
1149
1150
1151
1152
1153
1154 private void resolve( AttributeType attributeType, List<Throwable> errors )
1155 {
1156
1157
1158
1159 Set<String> processed = new HashSet<String>();
1160
1161
1162 processed.add( attributeType.getOid() );
1163
1164
1165 resolveRecursive( attributeType, processed, errors );
1166 }
1167
1168
1169 private List<AttributeType> getMustRecursive( List<AttributeType> musts, Set<ObjectClass> processed,
1170 ObjectClass objectClass )
1171 {
1172 if ( objectClass != null )
1173 {
1174 if ( processed.contains( objectClass ) )
1175 {
1176
1177
1178 return null;
1179 }
1180
1181 processed.add( objectClass );
1182
1183 for ( AttributeType must : objectClass.getMustAttributeTypes() )
1184 {
1185 musts.add( must );
1186 }
1187
1188 for ( ObjectClass superior : objectClass.getSuperiors() )
1189 {
1190 getMustRecursive( musts, processed, superior );
1191 }
1192 }
1193
1194 return musts;
1195 }
1196
1197
1198 private void resolve( ObjectClass objectClass, List<Throwable> errors )
1199 {
1200
1201
1202
1203 Set<String> processed = new HashSet<String>();
1204
1205
1206 processed.add( objectClass.getOid() );
1207
1208
1209 resolveRecursive( objectClass, processed, errors );
1210
1211
1212
1213 List<AttributeType> musts = getMustRecursive( new ArrayList<AttributeType>(), new HashSet<ObjectClass>(),
1214 objectClass );
1215
1216 if ( musts != null )
1217 {
1218 for ( AttributeType may : objectClass.getMayAttributeTypes() )
1219 {
1220 if ( musts.contains( may ) )
1221 {
1222
1223 LdapSchemaException ldapSchemaException = new LdapSchemaException(
1224 LdapSchemaExceptionCodes.OC_DUPLICATE_AT_IN_MAY_AND_MUST );
1225 ldapSchemaException.setSourceObject( objectClass );
1226 ldapSchemaException.setOtherObject( may );
1227 errors.add( ldapSchemaException );
1228 }
1229 }
1230 }
1231 }
1232
1233
1234 private void resolveRecursive( ObjectClass objectClass, Set<String> processed, List<Throwable> errors )
1235 {
1236
1237 List<String> superiorOids = objectClass.getSuperiorOids();
1238 ObjectClass superior = null;
1239
1240 for ( String superiorOid : superiorOids )
1241 {
1242
1243 try
1244 {
1245 superior = objectClassRegistry.lookup( superiorOid );
1246 }
1247 catch ( LdapException ne )
1248 {
1249
1250 if ( !processed.contains( superiorOid ) )
1251 {
1252 LdapSchemaException ldapSchemaException = new LdapSchemaException(
1253 LdapSchemaExceptionCodes.OC_NONEXISTENT_SUPERIOR, ne );
1254 ldapSchemaException.setSourceObject( objectClass );
1255 ldapSchemaException.setRelatedId( superiorOid );
1256 errors.add( ldapSchemaException );
1257 }
1258 }
1259
1260
1261
1262 if ( superior != null )
1263 {
1264 if ( !processed.contains( superior.getOid() ) )
1265 {
1266 resolveRecursive( superior, processed, errors );
1267 processed.add( objectClass.getOid() );
1268 }
1269 else
1270 {
1271
1272 LdapSchemaException ldapSchemaException = new LdapSchemaException(
1273 LdapSchemaExceptionCodes.OC_CYCLE_CLASS_HIERARCHY );
1274 ldapSchemaException.setSourceObject( objectClass );
1275 ldapSchemaException.setOtherObject( superior );
1276 errors.add( ldapSchemaException );
1277 return;
1278 }
1279 }
1280 }
1281
1282
1283 for ( String mayOid : objectClass.getMayAttributeTypeOids() )
1284 {
1285
1286 try
1287 {
1288 attributeTypeRegistry.lookup( mayOid );
1289 }
1290 catch ( LdapException ne )
1291 {
1292
1293 errors.add( ne );
1294 }
1295 }
1296
1297
1298 for ( String mustOid : objectClass.getMustAttributeTypeOids() )
1299 {
1300
1301 try
1302 {
1303 attributeTypeRegistry.lookup( mustOid );
1304 }
1305 catch ( LdapException ne )
1306 {
1307
1308 errors.add( ne );
1309 }
1310 }
1311
1312
1313 try
1314 {
1315 ObjectClassHelper.addToRegistries( objectClass, errors, this );
1316 }
1317 catch ( LdapException ne )
1318 {
1319
1320
1321 }
1322 }
1323
1324
1325
1326
1327
1328 public List<Throwable> add( List<Throwable> errors, SchemaObject schemaObject, boolean check ) throws LdapException
1329 {
1330
1331 boolean wasRelaxed = isRelaxed;
1332 setRelaxed();
1333
1334
1335 register( errors, schemaObject );
1336
1337
1338 associateWithSchema( errors, schemaObject );
1339
1340
1341 if ( check )
1342 {
1343 buildReference( errors, schemaObject );
1344 }
1345
1346
1347 schemaObject.lock();
1348
1349 if ( check && ( errors.isEmpty() ) )
1350 {
1351
1352 List<Throwable> checkErrors = checkRefInteg();
1353
1354 errors.addAll( checkErrors );
1355 }
1356
1357
1358 if ( !wasRelaxed )
1359 {
1360 setStrict();
1361 }
1362
1363
1364 return errors;
1365 }
1366
1367
1368
1369
1370
1371 public List<Throwable> delete( List<Throwable> errors, SchemaObject schemaObject ) throws LdapException
1372 {
1373
1374 boolean wasRelaxed = isRelaxed;
1375 setRelaxed();
1376
1377
1378 SchemaObject removed = unregister( errors, schemaObject );
1379
1380
1381 dissociateFromSchema( errors, removed );
1382
1383
1384 removeReference( errors, removed );
1385
1386 if ( errors.isEmpty() )
1387 {
1388
1389 List<Throwable> checkErrors = checkRefInteg();
1390
1391 errors.addAll( checkErrors );
1392 }
1393
1394
1395 if ( !wasRelaxed )
1396 {
1397 setStrict();
1398 }
1399
1400
1401 return errors;
1402 }
1403
1404
1405
1406
1407
1408
1409
1410
1411 public void schemaLoaded( Schema schema )
1412 {
1413 this.loadedSchemas.put( Strings.toLowerCase( schema.getSchemaName() ), schema );
1414 }
1415
1416
1417
1418
1419
1420
1421
1422
1423 public void schemaUnloaded( Schema schema )
1424 {
1425 this.loadedSchemas.remove( Strings.toLowerCase( schema.getSchemaName() ) );
1426 }
1427
1428
1429
1430
1431
1432
1433
1434 public Map<String, Schema> getLoadedSchemas()
1435 {
1436 return Collections.unmodifiableMap( loadedSchemas );
1437 }
1438
1439
1440
1441
1442
1443
1444 public Map<String, Set<SchemaObjectWrapper>> getObjectBySchemaName()
1445 {
1446 return schemaObjects;
1447 }
1448
1449
1450
1451
1452
1453 private String getSchemaName( SchemaObject schemaObject )
1454 {
1455 String schemaName = Strings.toLowerCase( schemaObject.getSchemaName() );
1456
1457 if ( loadedSchemas.containsKey( schemaName ) )
1458 {
1459 return schemaName;
1460 }
1461 else
1462 {
1463 return MetaSchemaConstants.SCHEMA_OTHER;
1464 }
1465 }
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475 public boolean contains( SchemaObject schemaObject )
1476 {
1477 String schemaName = schemaObject.getSchemaName();
1478
1479 Set<SchemaObjectWrapper> setSchemaObjects = schemaObjects.get( schemaName );
1480
1481 if ( ( setSchemaObjects == null ) || setSchemaObjects.isEmpty() )
1482 {
1483 return false;
1484 }
1485
1486 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( schemaObject );
1487
1488 return setSchemaObjects.contains( wrapper );
1489 }
1490
1491
1492
1493
1494
1495
1496
1497 public Set<SchemaObjectWrapper> addSchema( String schemaName )
1498 {
1499 Set<SchemaObjectWrapper> content = new HashSet<SchemaObjectWrapper>();
1500 schemaObjects.put( schemaName, content );
1501
1502 return content;
1503 }
1504
1505
1506
1507
1508
1509 private void register( List<Throwable> errors, SchemaObject schemaObject ) throws LdapException
1510 {
1511 LOG.debug( "Registering {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
1512
1513
1514 if ( schemaObject instanceof LoadableSchemaObject )
1515 {
1516
1517 }
1518 else
1519 {
1520 if ( globalOidRegistry.contains( schemaObject.getOid() ) )
1521 {
1522
1523 String msg = I18n.err( I18n.ERR_04301, schemaObject.getObjectType(), schemaObject.getOid() );
1524 LOG.error( msg );
1525 Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
1526 errors.add( error );
1527 return;
1528 }
1529 }
1530
1531 try
1532 {
1533
1534 switch ( schemaObject.getObjectType() )
1535 {
1536 case ATTRIBUTE_TYPE:
1537 attributeTypeRegistry.register( ( AttributeType ) schemaObject );
1538 break;
1539
1540 case COMPARATOR:
1541 comparatorRegistry.register( ( LdapComparator<?> ) schemaObject );
1542 break;
1543
1544 case DIT_CONTENT_RULE:
1545 ditContentRuleRegistry.register( ( DitContentRule ) schemaObject );
1546 break;
1547
1548 case DIT_STRUCTURE_RULE:
1549 ditStructureRuleRegistry.register( ( DitStructureRule ) schemaObject );
1550 break;
1551
1552 case LDAP_SYNTAX:
1553 ldapSyntaxRegistry.register( ( LdapSyntax ) schemaObject );
1554 break;
1555
1556 case MATCHING_RULE:
1557 matchingRuleRegistry.register( ( MatchingRule ) schemaObject );
1558 break;
1559
1560 case MATCHING_RULE_USE:
1561 matchingRuleUseRegistry.register( ( MatchingRuleUse ) schemaObject );
1562 break;
1563
1564 case NAME_FORM:
1565 nameFormRegistry.register( ( NameForm ) schemaObject );
1566 break;
1567
1568 case NORMALIZER:
1569 normalizerRegistry.register( ( Normalizer ) schemaObject );
1570 break;
1571
1572 case OBJECT_CLASS:
1573 objectClassRegistry.register( ( ObjectClass ) schemaObject );
1574 break;
1575
1576 case SYNTAX_CHECKER:
1577 syntaxCheckerRegistry.register( ( SyntaxChecker ) schemaObject );
1578 break;
1579 }
1580 }
1581 catch ( Exception e )
1582 {
1583 errors.add( e );
1584 }
1585 }
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595 public void associateWithSchema( List<Throwable> errors, SchemaObject schemaObject )
1596 {
1597 LOG.debug( "Registering {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
1598
1599
1600 if ( !( schemaObject instanceof LoadableSchemaObject ) && globalOidRegistry.contains( schemaObject.getOid() ) )
1601 {
1602
1603 String msg = I18n.err( I18n.ERR_04301, schemaObject.getObjectType(), schemaObject.getOid() );
1604 LOG.error( msg );
1605 Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
1606 errors.add( error );
1607 return;
1608 }
1609
1610
1611 String schemaName = getSchemaName( schemaObject );
1612
1613
1614 Set<SchemaObjectWrapper> content = schemaObjects.get( schemaName );
1615
1616 if ( content == null )
1617 {
1618 content = new HashSet<SchemaObjectWrapper>();
1619 schemaObjects.put( Strings.toLowerCase( schemaName ), content );
1620 }
1621
1622 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
1623
1624 if ( content.contains( schemaObjectWrapper ) )
1625 {
1626
1627
1628 LOG.info( "Registering of {}:{} failed, is already present in the Registries",
1629 schemaObject.getObjectType(), schemaObject.getOid() );
1630 }
1631 else
1632 {
1633
1634 content.add( schemaObjectWrapper );
1635
1636
1637
1638 if ( !( schemaObject instanceof LoadableSchemaObject ) )
1639 {
1640 try
1641 {
1642 globalOidRegistry.register( schemaObject );
1643 }
1644 catch ( LdapException ne )
1645 {
1646 errors.add( ne );
1647 return;
1648 }
1649 }
1650
1651 LOG.debug( "registered {} for OID {}", schemaObject.getName(), schemaObject.getOid() );
1652 }
1653 }
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664 public void dissociateFromSchema( List<Throwable> errors, SchemaObject schemaObject ) throws LdapException
1665 {
1666 LOG.debug( "Unregistering {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
1667
1668
1669 if ( !( schemaObject instanceof LoadableSchemaObject ) && !globalOidRegistry.contains( schemaObject.getOid() ) )
1670 {
1671
1672 String msg = I18n.err( I18n.ERR_04302, schemaObject.getObjectType(), schemaObject.getOid() );
1673 LOG.error( msg );
1674 Throwable error = new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
1675 errors.add( error );
1676 return;
1677 }
1678
1679
1680 String schemaName = getSchemaName( schemaObject );
1681 String oid = schemaObject.getOid();
1682
1683
1684 Set<SchemaObjectWrapper> content = schemaObjects.get( schemaName );
1685
1686 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
1687
1688 if ( !content.contains( schemaObjectWrapper ) )
1689 {
1690
1691
1692 LOG.info( "Unregistering of {}:{} failed, is not present in the Registries", schemaObject.getObjectType(),
1693 schemaObject.getOid() );
1694 }
1695 else
1696 {
1697
1698 content.remove( schemaObjectWrapper );
1699
1700
1701
1702 if ( !( schemaObject instanceof LoadableSchemaObject ) )
1703 {
1704 try
1705 {
1706 globalOidRegistry.unregister( oid );
1707 }
1708 catch ( LdapException ne )
1709 {
1710 errors.add( ne );
1711 return;
1712 }
1713 }
1714
1715 LOG.debug( "Unregistered {} for OID {}", schemaObject.getName(), schemaObject.getOid() );
1716 }
1717 }
1718
1719
1720
1721
1722
1723
1724
1725
1726 private SchemaObject unregister( List<Throwable> errors, SchemaObject schemaObject ) throws LdapException
1727 {
1728 LOG.debug( "Unregistering {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
1729
1730
1731 if ( schemaObject instanceof LoadableSchemaObject )
1732 {
1733
1734 }
1735 else
1736 {
1737 if ( !globalOidRegistry.contains( schemaObject.getOid() ) )
1738 {
1739
1740 String msg = I18n.err( I18n.ERR_04302, schemaObject.getObjectType(), schemaObject.getOid() );
1741 LOG.error( msg );
1742 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
1743 }
1744 }
1745
1746 SchemaObject unregistered = null;
1747
1748
1749 switch ( schemaObject.getObjectType() )
1750 {
1751 case ATTRIBUTE_TYPE:
1752 unregistered = attributeTypeRegistry.unregister( ( AttributeType ) schemaObject );
1753 break;
1754
1755 case COMPARATOR:
1756 unregistered = comparatorRegistry.unregister( ( LdapComparator<?> ) schemaObject );
1757 break;
1758
1759 case DIT_CONTENT_RULE:
1760 unregistered = ditContentRuleRegistry.unregister( ( DitContentRule ) schemaObject );
1761 break;
1762
1763 case DIT_STRUCTURE_RULE:
1764 unregistered = ditStructureRuleRegistry.unregister( ( DitStructureRule ) schemaObject );
1765 break;
1766
1767 case LDAP_SYNTAX:
1768 unregistered = ldapSyntaxRegistry.unregister( ( LdapSyntax ) schemaObject );
1769 break;
1770
1771 case MATCHING_RULE:
1772 unregistered = matchingRuleRegistry.unregister( ( MatchingRule ) schemaObject );
1773 break;
1774
1775 case MATCHING_RULE_USE:
1776 unregistered = matchingRuleUseRegistry.unregister( ( MatchingRuleUse ) schemaObject );
1777 break;
1778
1779 case NAME_FORM:
1780 unregistered = nameFormRegistry.unregister( ( NameForm ) schemaObject );
1781 break;
1782
1783 case NORMALIZER:
1784 unregistered = normalizerRegistry.unregister( ( Normalizer ) schemaObject );
1785 break;
1786
1787 case OBJECT_CLASS:
1788 unregistered = objectClassRegistry.unregister( ( ObjectClass ) schemaObject );
1789 break;
1790
1791 case SYNTAX_CHECKER:
1792 unregistered = syntaxCheckerRegistry.unregister( ( SyntaxChecker ) schemaObject );
1793 break;
1794 }
1795
1796 return unregistered;
1797 }
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807 public void dissociateFromSchema( SchemaObject schemaObject ) throws LdapException
1808 {
1809
1810 Set<SchemaObjectWrapper> content = schemaObjects.get( Strings.toLowerCase( schemaObject.getSchemaName() ) );
1811
1812 if ( content != null )
1813 {
1814 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
1815
1816 if ( content.contains( schemaObjectWrapper ) )
1817 {
1818
1819 content.remove( schemaObjectWrapper );
1820
1821
1822
1823 if ( !( schemaObject instanceof LoadableSchemaObject ) )
1824 {
1825 globalOidRegistry.unregister( schemaObject.getOid() );
1826 }
1827
1828 LOG.debug( "Unregistered {}:{}", schemaObject.getObjectType(), schemaObject.getOid() );
1829 }
1830 else
1831 {
1832
1833
1834 LOG.debug( "Unregistering of {}:{} failed, not found in Registries", schemaObject.getObjectType(),
1835 schemaObject.getOid() );
1836 }
1837 }
1838 }
1839
1840
1841
1842
1843
1844
1845
1846
1847 public boolean isReferenced( SchemaObject schemaObject )
1848 {
1849 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( schemaObject );
1850
1851 Set<SchemaObjectWrapper> set = usedBy.get( wrapper );
1852
1853 boolean referenced = ( set != null ) && ( set.size() != 0 );
1854
1855 if ( LOG.isDebugEnabled() )
1856 {
1857 if ( referenced )
1858 {
1859 LOG.debug( "The {}:{} is referenced", schemaObject.getObjectType(), schemaObject.getOid() );
1860 }
1861 else
1862 {
1863 LOG.debug( "The {}:{} is not referenced", schemaObject.getObjectType(), schemaObject.getOid() );
1864 }
1865 }
1866
1867 return referenced;
1868 }
1869
1870
1871
1872
1873
1874
1875
1876
1877 public Set<SchemaObjectWrapper> getUsedBy( SchemaObject schemaObject )
1878 {
1879 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( schemaObject );
1880
1881 return usedBy.get( wrapper );
1882 }
1883
1884
1885
1886
1887
1888 public String dumpUsedBy()
1889 {
1890 StringBuilder sb = new StringBuilder();
1891
1892 sb.append( "USED BY :\n" );
1893
1894 try
1895 {
1896 for ( SchemaObjectWrapper wrapper : usedBy.keySet() )
1897 {
1898 sb.append( wrapper.get().getObjectType() ).append( '[' ).append( wrapper.get().getOid() )
1899 .append( "] : {" );
1900
1901 boolean isFirst = true;
1902
1903 for ( SchemaObjectWrapper uses : usedBy.get( wrapper ) )
1904 {
1905 if ( isFirst )
1906 {
1907 isFirst = false;
1908 }
1909 else
1910 {
1911 sb.append( ", " );
1912 }
1913
1914 sb.append( uses.get().getObjectType() ).append( '[' ).append( wrapper.get().getOid() ).append( "]" );
1915 }
1916
1917 sb.append( "}\n" );
1918 }
1919 }
1920 catch ( Exception e )
1921 {
1922 e.printStackTrace();
1923 }
1924
1925 return sb.toString();
1926 }
1927
1928
1929
1930
1931
1932 public String dumpUsing()
1933 {
1934 StringBuilder sb = new StringBuilder();
1935
1936 sb.append( "USING :\n" );
1937
1938 try
1939 {
1940 for ( SchemaObjectWrapper wrapper : using.keySet() )
1941 {
1942 sb.append( wrapper.get().getObjectType() ).append( '[' ).append( wrapper.get().getOid() )
1943 .append( "] : {" );
1944
1945 boolean isFirst = true;
1946
1947 for ( SchemaObjectWrapper uses : using.get( wrapper ) )
1948 {
1949 if ( isFirst )
1950 {
1951 isFirst = false;
1952 }
1953 else
1954 {
1955 sb.append( ", " );
1956 }
1957
1958 sb.append( uses.get().getObjectType() ).append( '[' ).append( wrapper.get().getOid() ).append( "]" );
1959 }
1960
1961 sb.append( "}\n" );
1962 }
1963 }
1964 catch ( Exception e )
1965 {
1966 e.printStackTrace();
1967 }
1968
1969 return sb.toString();
1970 }
1971
1972
1973
1974
1975
1976
1977
1978
1979 public Set<SchemaObjectWrapper> getUsing( SchemaObject schemaObject )
1980 {
1981 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( schemaObject );
1982
1983 return using.get( wrapper );
1984 }
1985
1986
1987
1988
1989
1990
1991
1992
1993 private void addUsing( SchemaObject reference, SchemaObject referee )
1994 {
1995 if ( ( reference == null ) || ( referee == null ) )
1996 {
1997 return;
1998 }
1999
2000 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( reference );
2001
2002 Set<SchemaObjectWrapper> uses = getUsing( reference );
2003
2004 if ( uses == null )
2005 {
2006 uses = new HashSet<SchemaObjectWrapper>();
2007 }
2008
2009 uses.add( new SchemaObjectWrapper( referee ) );
2010
2011
2012 using.put( wrapper, uses );
2013 }
2014
2015
2016
2017
2018
2019
2020
2021
2022 public void addReference( SchemaObject base, SchemaObject referenced )
2023 {
2024 if ( LOG.isDebugEnabled() )
2025 {
2026 LOG.debug( dump( "add", base, referenced ) );
2027 }
2028
2029 addUsing( base, referenced );
2030 addUsedBy( referenced, base );
2031
2032
2033
2034 if ( LOG.isTraceEnabled() )
2035 {
2036 LOG.trace( dumpUsedBy() );
2037 LOG.trace( dumpUsing() );
2038 }
2039 }
2040
2041
2042
2043
2044
2045
2046
2047
2048 private void addUsedBy( SchemaObject referee, SchemaObject reference )
2049 {
2050 if ( ( reference == null ) || ( referee == null ) )
2051 {
2052 return;
2053 }
2054
2055 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( referee );
2056
2057 Set<SchemaObjectWrapper> uses = getUsedBy( referee );
2058
2059 if ( uses == null )
2060 {
2061 uses = new HashSet<SchemaObjectWrapper>();
2062 }
2063
2064 uses.add( new SchemaObjectWrapper( reference ) );
2065
2066
2067 usedBy.put( wrapper, uses );
2068 }
2069
2070
2071
2072
2073
2074
2075
2076
2077 private void delUsing( SchemaObject reference, SchemaObject referee )
2078 {
2079 if ( ( reference == null ) || ( referee == null ) )
2080 {
2081 return;
2082 }
2083
2084 Set<SchemaObjectWrapper> uses = getUsing( reference );
2085
2086 if ( uses == null )
2087 {
2088 return;
2089 }
2090
2091 uses.remove( new SchemaObjectWrapper( referee ) );
2092
2093 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( reference );
2094
2095 if ( uses.size() == 0 )
2096 {
2097 using.remove( wrapper );
2098 }
2099 else
2100 {
2101 using.put( wrapper, uses );
2102 }
2103 }
2104
2105
2106
2107
2108
2109
2110
2111
2112 private void delUsedBy( SchemaObject referee, SchemaObject reference )
2113 {
2114 if ( ( reference == null ) || ( referee == null ) )
2115 {
2116 return;
2117 }
2118
2119 Set<SchemaObjectWrapper> uses = getUsedBy( referee );
2120
2121 if ( uses == null )
2122 {
2123 return;
2124 }
2125
2126 uses.remove( new SchemaObjectWrapper( reference ) );
2127
2128 SchemaObjectWrapper wrapper = new SchemaObjectWrapper( referee );
2129
2130 if ( uses.size() == 0 )
2131 {
2132 usedBy.remove( wrapper );
2133 }
2134 else
2135 {
2136 usedBy.put( wrapper, uses );
2137 }
2138 }
2139
2140
2141
2142
2143
2144
2145
2146
2147 public void delReference( SchemaObject base, SchemaObject referenced )
2148 {
2149 if ( LOG.isDebugEnabled() )
2150 {
2151 LOG.debug( dump( "del", base, referenced ) );
2152 }
2153
2154 delUsing( base, referenced );
2155 delUsedBy( referenced, base );
2156
2157 if ( LOG.isDebugEnabled() )
2158 {
2159 LOG.debug( dumpUsedBy() );
2160 LOG.debug( dumpUsing() );
2161 }
2162 }
2163
2164
2165
2166
2167
2168 private String dump( String op, SchemaObject reference, SchemaObject referee )
2169 {
2170 return op + " : " + reference.getObjectType() + "[" + reference.getOid() + "]/[" + referee.getObjectType()
2171 + "[" + referee.getOid() + "]";
2172 }
2173
2174
2175 private boolean checkReferences( SchemaObject reference, SchemaObject referee, String message )
2176 {
2177 SchemaObjectWrapper referenceWrapper = new SchemaObjectWrapper( reference );
2178 SchemaObjectWrapper refereeWrapper = new SchemaObjectWrapper( referee );
2179
2180
2181 if ( !using.containsKey( referenceWrapper ) )
2182 {
2183 LOG.debug( "The Syntax {}:{} does not reference any " + message, reference.getObjectType(), reference
2184 .getOid() );
2185
2186 return false;
2187 }
2188
2189 Set<SchemaObjectWrapper> usings = using.get( referenceWrapper );
2190
2191 if ( !usings.contains( refereeWrapper ) )
2192 {
2193 LOG.debug( "The {}:{} does not reference any " + message, reference.getObjectType(), reference.getOid() );
2194
2195 return false;
2196 }
2197
2198
2199 if ( !usedBy.containsKey( refereeWrapper ) )
2200 {
2201 LOG.debug( "The {}:{} is not referenced by any " + message, referee.getObjectType(), referee.getOid() );
2202
2203 return false;
2204 }
2205
2206 Set<SchemaObjectWrapper> used = usedBy.get( refereeWrapper );
2207
2208 if ( !used.contains( referenceWrapper ) )
2209 {
2210 LOG.debug( "The {}:{} is not referenced by any " + message, referee.getObjectType(), referee.getOid() );
2211
2212 return false;
2213 }
2214
2215 return true;
2216 }
2217
2218
2219
2220
2221
2222
2223
2224 public boolean check()
2225 {
2226
2227 LOG.debug( "Checking Syntaxes" );
2228
2229 for ( LdapSyntax syntax : ldapSyntaxRegistry )
2230 {
2231
2232 if ( syntax.getSyntaxChecker() == null )
2233 {
2234 LOG.debug( "The Syntax {} has no SyntaxChecker", syntax );
2235
2236 return false;
2237 }
2238
2239 if ( !syntaxCheckerRegistry.contains( syntax.getSyntaxChecker().getOid() ) )
2240 {
2241 LOG.debug( "Cannot find the SyntaxChecker {} for the Syntax {}", syntax.getSyntaxChecker().getOid(),
2242 syntax );
2243
2244 return false;
2245 }
2246
2247
2248 if ( !checkReferences( syntax, syntax.getSyntaxChecker(), "SyntaxChecker" ) )
2249 {
2250 return false;
2251 }
2252 }
2253
2254
2255 LOG.debug( "Checking MatchingRules..." );
2256
2257 for ( MatchingRule matchingRule : matchingRuleRegistry )
2258 {
2259
2260 if ( matchingRule.getNormalizer() == null )
2261 {
2262 LOG.debug( "The MatchingRule {} has no Normalizer", matchingRule );
2263
2264 return false;
2265 }
2266
2267
2268 if ( !normalizerRegistry.contains( matchingRule.getNormalizer().getOid() ) )
2269 {
2270 LOG.debug( "Cannot find the Normalizer {} for the MatchingRule {}", matchingRule.getNormalizer()
2271 .getOid(), matchingRule );
2272
2273 return false;
2274 }
2275
2276
2277 if ( matchingRule.getLdapComparator() == null )
2278 {
2279 LOG.debug( "The MatchingRule {} has no Comparator", matchingRule );
2280
2281 return false;
2282 }
2283
2284 if ( !comparatorRegistry.contains( matchingRule.getLdapComparator().getOid() ) )
2285 {
2286 LOG.debug( "Cannot find the Comparator {} for the MatchingRule {}", matchingRule.getLdapComparator()
2287 .getOid(), matchingRule );
2288
2289 return false;
2290 }
2291
2292
2293 if ( matchingRule.getSyntax() == null )
2294 {
2295 LOG.debug( "The MatchingRule {} has no Syntax", matchingRule );
2296
2297 return false;
2298 }
2299
2300 if ( !ldapSyntaxRegistry.contains( matchingRule.getSyntax().getOid() ) )
2301 {
2302 LOG.debug( "Cannot find the Syntax {} for the MatchingRule {}", matchingRule.getSyntax().getOid(),
2303 matchingRule );
2304
2305 return false;
2306 }
2307
2308
2309 if ( !checkReferences( matchingRule, matchingRule.getSyntax(), "Syntax" ) )
2310 {
2311 return false;
2312 }
2313
2314
2315 if ( !checkReferences( matchingRule, matchingRule.getNormalizer(), "Normalizer" ) )
2316 {
2317 return false;
2318 }
2319
2320
2321 if ( !checkReferences( matchingRule, matchingRule.getLdapComparator(), "Comparator" ) )
2322 {
2323 return false;
2324 }
2325 }
2326
2327
2328 LOG.debug( "Checking ObjectClasses..." );
2329
2330 for ( ObjectClass objectClass : objectClassRegistry )
2331 {
2332
2333 if ( objectClass.getMayAttributeTypes() != null )
2334 {
2335 for ( AttributeType may : objectClass.getMayAttributeTypes() )
2336 {
2337 if ( !attributeTypeRegistry.contains( may.getOid() ) )
2338 {
2339 LOG.debug( "Cannot find the AttributeType {} for the ObjectClass {} MAY", may, objectClass );
2340
2341 return false;
2342 }
2343
2344
2345 if ( !checkReferences( objectClass, may, "AttributeType" ) )
2346 {
2347 return false;
2348 }
2349 }
2350 }
2351
2352
2353 if ( objectClass.getMustAttributeTypes() != null )
2354 {
2355 for ( AttributeType must : objectClass.getMustAttributeTypes() )
2356 {
2357 if ( !attributeTypeRegistry.contains( must.getOid() ) )
2358 {
2359 LOG.debug( "Cannot find the AttributeType {} for the ObjectClass {} MUST", must, objectClass );
2360
2361 return false;
2362 }
2363
2364
2365 if ( !checkReferences( objectClass, must, "AttributeType" ) )
2366 {
2367 return false;
2368 }
2369 }
2370 }
2371
2372
2373 if ( objectClass.getSuperiors() != null )
2374 {
2375 for ( ObjectClass superior : objectClass.getSuperiors() )
2376 {
2377 if ( !objectClassRegistry.contains( objectClass.getOid() ) )
2378 {
2379 LOG.debug( "Cannot find the ObjectClass {} for the ObjectClass {} SUPERIORS", superior,
2380 objectClass );
2381
2382 return false;
2383 }
2384
2385
2386 if ( !checkReferences( objectClass, superior, "ObjectClass" ) )
2387 {
2388 return false;
2389 }
2390 }
2391 }
2392 }
2393
2394
2395 LOG.debug( "Checking AttributeTypes..." );
2396
2397 for ( AttributeType attributeType : attributeTypeRegistry )
2398 {
2399
2400 if ( attributeType.getSyntax() == null )
2401 {
2402 LOG.debug( "The AttributeType {} has no Syntax", attributeType );
2403
2404 return false;
2405 }
2406
2407 if ( !ldapSyntaxRegistry.contains( attributeType.getSyntax().getOid() ) )
2408 {
2409 LOG.debug( "Cannot find the Syntax {} for the AttributeType {}", attributeType.getSyntax().getOid(),
2410 attributeType );
2411
2412 return false;
2413 }
2414
2415
2416 if ( !checkReferences( attributeType, attributeType.getSyntax(), "AttributeType" ) )
2417 {
2418 return false;
2419 }
2420
2421
2422 if ( attributeType.getEquality() != null )
2423 {
2424 if ( !matchingRuleRegistry.contains( attributeType.getEquality().getOid() ) )
2425 {
2426 LOG.debug( "Cannot find the MatchingRule {} for the AttributeType {}", attributeType.getEquality()
2427 .getOid(), attributeType );
2428
2429 return false;
2430 }
2431
2432
2433 if ( !checkReferences( attributeType, attributeType.getEquality(), "AttributeType" ) )
2434 {
2435 return false;
2436 }
2437 }
2438
2439
2440 if ( attributeType.getOrdering() != null )
2441 {
2442 if ( !matchingRuleRegistry.contains( attributeType.getOrdering().getOid() ) )
2443 {
2444 LOG.debug( "Cannot find the MatchingRule {} for the AttributeType {}", attributeType.getOrdering()
2445 .getOid(), attributeType );
2446
2447 return false;
2448 }
2449
2450
2451 if ( !checkReferences( attributeType, attributeType.getOrdering(), "AttributeType" ) )
2452 {
2453 return false;
2454 }
2455 }
2456
2457
2458 if ( attributeType.getSubstring() != null )
2459 {
2460 if ( !matchingRuleRegistry.contains( attributeType.getSubstring().getOid() ) )
2461 {
2462 LOG.debug( "Cannot find the MatchingRule {} for the AttributeType {}", attributeType.getSubstring()
2463 .getOid(), attributeType );
2464
2465 return false;
2466 }
2467
2468
2469 if ( !checkReferences( attributeType, attributeType.getSubstring(), "AttributeType" ) )
2470 {
2471 return false;
2472 }
2473 }
2474
2475
2476 if ( attributeType.getSuperior() != null )
2477 {
2478 AttributeType superior = attributeType.getSuperior();
2479
2480 if ( !attributeTypeRegistry.contains( superior.getOid() ) )
2481 {
2482 LOG.debug( "Cannot find the AttributeType {} for the AttributeType {} SUPERIOR", superior,
2483 attributeType );
2484
2485 return false;
2486 }
2487
2488
2489 if ( !checkReferences( attributeType, superior, "AttributeType" ) )
2490 {
2491 return false;
2492 }
2493 }
2494 }
2495
2496 return true;
2497 }
2498
2499
2500
2501
2502
2503
2504
2505
2506 public Registries clone() throws CloneNotSupportedException
2507 {
2508
2509 Registries clone = ( Registries ) super.clone();
2510
2511
2512 clone.globalOidRegistry = globalOidRegistry.copy();
2513
2514
2515 clone.attributeTypeRegistry = attributeTypeRegistry.copy();
2516 clone.comparatorRegistry = comparatorRegistry.copy();
2517 clone.ditContentRuleRegistry = ditContentRuleRegistry.copy();
2518 clone.ditStructureRuleRegistry = ditStructureRuleRegistry.copy();
2519 clone.ldapSyntaxRegistry = ldapSyntaxRegistry.copy();
2520 clone.matchingRuleRegistry = matchingRuleRegistry.copy();
2521 clone.matchingRuleUseRegistry = matchingRuleUseRegistry.copy();
2522 clone.nameFormRegistry = nameFormRegistry.copy();
2523 clone.normalizerRegistry = normalizerRegistry.copy();
2524 clone.objectClassRegistry = objectClassRegistry.copy();
2525 clone.syntaxCheckerRegistry = syntaxCheckerRegistry.copy();
2526
2527
2528 for ( AttributeType attributeType : clone.attributeTypeRegistry )
2529 {
2530 clone.globalOidRegistry.put( attributeType );
2531 }
2532
2533 for ( DitContentRule ditContentRule : clone.ditContentRuleRegistry )
2534 {
2535 clone.globalOidRegistry.put( ditContentRule );
2536 }
2537
2538 for ( DitStructureRule ditStructureRule : clone.ditStructureRuleRegistry )
2539 {
2540 clone.globalOidRegistry.put( ditStructureRule );
2541 }
2542
2543 for ( MatchingRule matchingRule : clone.matchingRuleRegistry )
2544 {
2545 clone.globalOidRegistry.put( matchingRule );
2546 }
2547
2548 for ( MatchingRuleUse matchingRuleUse : clone.matchingRuleUseRegistry )
2549 {
2550 clone.globalOidRegistry.put( matchingRuleUse );
2551 }
2552
2553 for ( NameForm nameForm : clone.nameFormRegistry )
2554 {
2555 clone.globalOidRegistry.put( nameForm );
2556 }
2557
2558 for ( ObjectClass objectClass : clone.objectClassRegistry )
2559 {
2560 clone.globalOidRegistry.put( objectClass );
2561 }
2562
2563 for ( LdapSyntax syntax : clone.ldapSyntaxRegistry )
2564 {
2565 clone.globalOidRegistry.put( syntax );
2566 }
2567
2568
2569 clone.loadedSchemas = new HashMap<String, Schema>();
2570
2571 for ( String schemaName : loadedSchemas.keySet() )
2572 {
2573
2574 clone.loadedSchemas.put( schemaName, loadedSchemas.get( schemaName ) );
2575 }
2576
2577
2578
2579 clone.using = new HashMap<SchemaObjectWrapper, Set<SchemaObjectWrapper>>();
2580 clone.usedBy = new HashMap<SchemaObjectWrapper, Set<SchemaObjectWrapper>>();
2581
2582
2583 clone.buildReferences();
2584
2585
2586 clone.checkRefInteg();
2587
2588 clone.schemaObjects = new HashMap<String, Set<SchemaObjectWrapper>>();
2589
2590
2591
2592 for ( String schemaName : schemaObjects.keySet() )
2593 {
2594 Set<SchemaObjectWrapper> objects = new HashSet<SchemaObjectWrapper>();
2595
2596 for ( SchemaObjectWrapper schemaObjectWrapper : schemaObjects.get( schemaName ) )
2597 {
2598 SchemaObject original = schemaObjectWrapper.get();
2599
2600 try
2601 {
2602 if ( !( original instanceof LoadableSchemaObject ) )
2603 {
2604 SchemaObject copy = clone.globalOidRegistry.getSchemaObject( original.getOid() );
2605 SchemaObjectWrapper newWrapper = new SchemaObjectWrapper( copy );
2606 objects.add( newWrapper );
2607 }
2608 else
2609 {
2610 SchemaObjectWrapper newWrapper = new SchemaObjectWrapper( original );
2611 objects.add( newWrapper );
2612 }
2613 }
2614 catch ( LdapException ne )
2615 {
2616
2617 }
2618 }
2619
2620 clone.schemaObjects.put( schemaName, objects );
2621 }
2622
2623 return clone;
2624 }
2625
2626
2627
2628
2629
2630
2631
2632
2633 public boolean isRelaxed()
2634 {
2635 return isRelaxed;
2636 }
2637
2638
2639
2640
2641
2642
2643
2644 public boolean isStrict()
2645 {
2646 return !isRelaxed;
2647 }
2648
2649
2650
2651
2652
2653
2654 public void setRelaxed()
2655 {
2656 isRelaxed = RELAXED;
2657 }
2658
2659
2660
2661
2662
2663
2664 public void setStrict()
2665 {
2666 isRelaxed = STRICT;
2667 }
2668
2669
2670
2671
2672
2673
2674
2675 public boolean isDisabledAccepted()
2676 {
2677 return disabledAccepted;
2678 }
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688 public Set<SchemaObjectWrapper> getReferencing( SchemaObject schemaObject )
2689 {
2690 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
2691
2692 return usedBy.get( schemaObjectWrapper );
2693 }
2694
2695
2696
2697
2698
2699
2700
2701
2702 public void setDisabledAccepted( boolean disabledAccepted )
2703 {
2704 this.disabledAccepted = disabledAccepted;
2705 }
2706
2707
2708
2709
2710
2711
2712
2713 public void clear() throws LdapException
2714 {
2715
2716 if ( attributeTypeRegistry != null )
2717 {
2718 attributeTypeRegistry.clear();
2719 }
2720
2721
2722 if ( comparatorRegistry != null )
2723 {
2724 comparatorRegistry.clear();
2725 }
2726
2727
2728 if ( ditContentRuleRegistry != null )
2729 {
2730 ditContentRuleRegistry.clear();
2731 }
2732
2733
2734 if ( ditStructureRuleRegistry != null )
2735 {
2736 ditStructureRuleRegistry.clear();
2737 }
2738
2739
2740 if ( matchingRuleRegistry != null )
2741 {
2742 matchingRuleRegistry.clear();
2743 }
2744
2745
2746 if ( matchingRuleUseRegistry != null )
2747 {
2748 matchingRuleUseRegistry.clear();
2749 }
2750
2751
2752 if ( nameFormRegistry != null )
2753 {
2754 nameFormRegistry.clear();
2755 }
2756
2757
2758 if ( normalizerRegistry != null )
2759 {
2760 normalizerRegistry.clear();
2761 }
2762
2763
2764 if ( objectClassRegistry != null )
2765 {
2766 objectClassRegistry.clear();
2767 }
2768
2769
2770 if ( ldapSyntaxRegistry != null )
2771 {
2772 ldapSyntaxRegistry.clear();
2773 }
2774
2775
2776 if ( syntaxCheckerRegistry != null )
2777 {
2778 syntaxCheckerRegistry.clear();
2779 }
2780
2781
2782 for ( String schemaName : schemaObjects.keySet() )
2783 {
2784 Set<SchemaObjectWrapper> wrapperSet = schemaObjects.get( schemaName );
2785
2786 wrapperSet.clear();
2787 }
2788
2789 schemaObjects.clear();
2790
2791
2792 for ( SchemaObjectWrapper wrapper : usedBy.keySet() )
2793 {
2794 Set<SchemaObjectWrapper> wrapperSet = usedBy.get( wrapper );
2795
2796 wrapperSet.clear();
2797 }
2798
2799 usedBy.clear();
2800
2801
2802 for ( SchemaObjectWrapper wrapper : using.keySet() )
2803 {
2804 Set<SchemaObjectWrapper> wrapperSet = using.get( wrapper );
2805
2806 wrapperSet.clear();
2807 }
2808
2809 using.clear();
2810
2811
2812 globalOidRegistry.clear();
2813
2814
2815 loadedSchemas.clear();
2816 }
2817
2818
2819
2820
2821
2822 public String toString()
2823 {
2824 StringBuilder sb = new StringBuilder();
2825
2826 sb.append( "Registries [" );
2827
2828 if ( isRelaxed )
2829 {
2830 sb.append( "RELAXED," );
2831 }
2832 else
2833 {
2834 sb.append( "STRICT," );
2835 }
2836
2837 if ( disabledAccepted )
2838 {
2839 sb.append( " Disabled accepted] :\n" );
2840 }
2841 else
2842 {
2843 sb.append( " Disabled forbidden] :\n" );
2844 }
2845
2846 sb.append( "loaded schemas [" );
2847 boolean isFirst = true;
2848
2849 for ( String schema : loadedSchemas.keySet() )
2850 {
2851 if ( isFirst )
2852 {
2853 isFirst = false;
2854 }
2855 else
2856 {
2857 sb.append( ", " );
2858 }
2859
2860 sb.append( schema );
2861 }
2862
2863 sb.append( "]\n" );
2864
2865 sb.append( "AttributeTypes : " ).append( attributeTypeRegistry.size() ).append( "\n" );
2866 sb.append( "Comparators : " ).append( comparatorRegistry.size() ).append( "\n" );
2867 sb.append( "DitContentRules : " ).append( ditContentRuleRegistry.size() ).append( "\n" );
2868 sb.append( "DitStructureRules : " ).append( ditStructureRuleRegistry.size() ).append( "\n" );
2869 sb.append( "MatchingRules : " ).append( matchingRuleRegistry.size() ).append( "\n" );
2870 sb.append( "MatchingRuleUses : " ).append( matchingRuleUseRegistry.size() ).append( "\n" );
2871 sb.append( "NameForms : " ).append( nameFormRegistry.size() ).append( "\n" );
2872 sb.append( "Normalizers : " ).append( normalizerRegistry.size() ).append( "\n" );
2873 sb.append( "ObjectClasses : " ).append( objectClassRegistry.size() ).append( "\n" );
2874 sb.append( "Syntaxes : " ).append( ldapSyntaxRegistry.size() ).append( "\n" );
2875 sb.append( "SyntaxCheckers : " ).append( syntaxCheckerRegistry.size() ).append( "\n" );
2876
2877 sb.append( "GlobalOidRegistry : " ).append( globalOidRegistry.size() ).append( '\n' );
2878
2879 return sb.toString();
2880 }
2881 }