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