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.helper;
21
22 import java.util.HashSet;
23 import java.util.Set;
24
25 import org.apache.directory.api.i18n.I18n;
26 import org.apache.directory.api.ldap.model.exception.LdapException;
27 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
28 import org.apache.directory.api.ldap.model.exception.LdapSchemaExceptionCodes;
29 import org.apache.directory.api.ldap.model.schema.AttributeType;
30 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
31 import org.apache.directory.api.ldap.model.schema.MatchingRule;
32 import org.apache.directory.api.ldap.model.schema.SchemaErrorHandler;
33 import org.apache.directory.api.ldap.model.schema.UsageEnum;
34 import org.apache.directory.api.ldap.model.schema.registries.AttributeTypeRegistry;
35 import org.apache.directory.api.ldap.model.schema.registries.Registries;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43
44
45 public final class AttributeTypeHelper
46 {
47
48 private static final Logger LOG = LoggerFactory.getLogger( AttributeTypeHelper.class );
49
50 private AttributeTypeHelper()
51 {
52 }
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public static void addToRegistries( AttributeType attributeType, SchemaErrorHandler errorHandler, Registries registries ) throws LdapException
67 {
68 if ( registries != null )
69 {
70 try
71 {
72 attributeType.unlock();
73 AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
74
75
76 if ( !buildSuperior( attributeType, errorHandler, registries ) )
77 {
78
79 return;
80 }
81
82
83 buildSyntax( attributeType, errorHandler, registries );
84
85
86 buildEquality( attributeType, errorHandler, registries );
87
88
89 buildOrdering( attributeType, errorHandler, registries );
90
91
92 buildSubstring( attributeType, errorHandler, registries );
93
94
95 checkUsage( attributeType, errorHandler );
96
97
98 checkCollective( attributeType, errorHandler );
99
100
101 attributeTypeRegistry.addMappingFor( attributeType );
102
103
104 attributeTypeRegistry.registerDescendants( attributeType, attributeType.getSuperior() );
105
106
107
108
109
110
111
112 if ( attributeType.getEquality() != null )
113 {
114 registries.addReference( attributeType, attributeType.getEquality() );
115 }
116
117 if ( attributeType.getOrdering() != null )
118 {
119 registries.addReference( attributeType, attributeType.getOrdering() );
120 }
121
122 if ( attributeType.getSubstring() != null )
123 {
124 registries.addReference( attributeType, attributeType.getSubstring() );
125 }
126
127 if ( attributeType.getSyntax() != null )
128 {
129 registries.addReference( attributeType, attributeType.getSyntax() );
130 }
131
132 if ( attributeType.getSuperior() != null )
133 {
134 registries.addReference( attributeType, attributeType.getSuperior() );
135 }
136 }
137 finally
138 {
139 attributeType.lock();
140 }
141 }
142 }
143
144
145
146
147
148
149
150
151
152
153 private static boolean buildSuperior( AttributeType attributeType, SchemaErrorHandler errorHandler,
154 Registries registries )
155 {
156 AttributeType currentSuperior;
157 AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
158
159 String superiorOid = attributeType.getSuperiorOid();
160
161 if ( superiorOid != null )
162 {
163
164 try
165 {
166 currentSuperior = ( AttributeType ) attributeTypeRegistry.lookup( superiorOid );
167 }
168 catch ( Exception e )
169 {
170
171 String msg = I18n.err( I18n.ERR_13752_CANNOT_FIND_SUPERIOR, superiorOid, attributeType.getName() );
172
173 LdapSchemaException ldapSchemaException = new LdapSchemaException(
174 LdapSchemaExceptionCodes.AT_NONEXISTENT_SUPERIOR, msg, e );
175 ldapSchemaException.setSourceObject( attributeType );
176 ldapSchemaException.setRelatedId( superiorOid );
177 errorHandler.handle( LOG, msg, ldapSchemaException );
178
179
180 return false;
181 }
182
183 if ( currentSuperior != null )
184 {
185
186 if ( currentSuperior.isCollective() )
187 {
188 String msg = I18n.err( I18n.ERR_13776_CANNOT_SUBTYPE_COLLECTIVE,
189 currentSuperior, attributeType.getName() );
190
191 LdapSchemaException ldapSchemaException = new LdapSchemaException(
192 LdapSchemaExceptionCodes.AT_CANNOT_SUBTYPE_COLLECTIVE_AT, msg );
193 ldapSchemaException.setSourceObject( attributeType );
194 errorHandler.handle( LOG, msg, ldapSchemaException );
195
196 return false;
197 }
198
199 attributeType.setSuperior( currentSuperior );
200
201
202
203
204 if ( currentSuperior.getSuperior() == null )
205 {
206 registries.buildReference( currentSuperior );
207 }
208
209
210 try
211 {
212 attributeTypeRegistry.registerDescendants( attributeType, currentSuperior );
213 }
214 catch ( LdapException ne )
215 {
216 errorHandler.handle( LOG, ne.getMessage(), ne );
217
218 return false;
219 }
220
221
222 Set<String> superiors = new HashSet<>();
223 superiors.add( attributeType.getOid() );
224 AttributeType tmp = currentSuperior;
225 boolean isOk = true;
226
227 while ( tmp != null )
228 {
229 if ( superiors.contains( tmp.getOid() ) )
230 {
231
232
233 String msg = I18n.err( I18n.ERR_13753_CYCLE_DETECTED, attributeType.getName() );
234
235 LdapSchemaException ldapSchemaException = new LdapSchemaException(
236 LdapSchemaExceptionCodes.AT_CYCLE_TYPE_HIERARCHY, msg );
237 ldapSchemaException.setSourceObject( attributeType );
238 errorHandler.handle( LOG, msg, ldapSchemaException );
239
240 isOk = false;
241
242 break;
243 }
244 else
245 {
246 superiors.add( tmp.getOid() );
247 tmp = tmp.getSuperior();
248 }
249 }
250
251 superiors.clear();
252
253 return isOk;
254 }
255 else
256 {
257
258 String msg = I18n.err( I18n.ERR_13752_CANNOT_FIND_SUPERIOR, superiorOid, attributeType.getName() );
259
260 LdapSchemaException ldapSchemaException = new LdapSchemaException(
261 LdapSchemaExceptionCodes.AT_NONEXISTENT_SUPERIOR, msg );
262 ldapSchemaException.setSourceObject( attributeType );
263 ldapSchemaException.setRelatedId( superiorOid );
264 errorHandler.handle( LOG, msg, ldapSchemaException );
265
266
267 return false;
268 }
269 }
270 else
271 {
272
273 return true;
274 }
275 }
276
277
278
279
280
281
282
283
284
285 private static void buildSyntax( AttributeType attributeType, SchemaErrorHandler errorHandler,
286 Registries registries )
287 {
288 String syntaxOid = attributeType.getSyntaxOid();
289
290 if ( syntaxOid != null )
291 {
292 LdapSyntax currentSyntax = null;
293
294 try
295 {
296 currentSyntax = registries.getLdapSyntaxRegistry().lookup( syntaxOid );
297 }
298 catch ( LdapException ne )
299 {
300
301 String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
302
303 LdapSchemaException ldapSchemaException = new LdapSchemaException(
304 LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg, ne );
305 ldapSchemaException.setSourceObject( attributeType );
306 ldapSchemaException.setRelatedId( syntaxOid );
307 errorHandler.handle( LOG, msg, ldapSchemaException );
308
309 return;
310 }
311
312 if ( currentSyntax != null )
313 {
314
315 attributeType.setSyntax( currentSyntax );
316 }
317 else
318 {
319
320 String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
321
322 LdapSchemaException ldapSchemaException = new LdapSchemaException(
323 LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg );
324 ldapSchemaException.setSourceObject( attributeType );
325 ldapSchemaException.setRelatedId( syntaxOid );
326 errorHandler.handle( LOG, msg, ldapSchemaException );
327 }
328 }
329 else
330 {
331
332 if ( attributeType.getSuperior() != null )
333 {
334 if ( attributeType.getSuperior().getSyntax() != null )
335 {
336 attributeType.setSyntax( attributeType.getSuperior().getSyntax() );
337 }
338 else
339 {
340 String msg = I18n.err( I18n.ERR_13754_CANNOT_FIND_SYNTAX, syntaxOid, attributeType.getName() );
341
342 LdapSchemaException ldapSchemaException = new LdapSchemaException(
343 LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg );
344 ldapSchemaException.setSourceObject( attributeType );
345 ldapSchemaException.setRelatedId( syntaxOid );
346 errorHandler.handle( LOG, msg, ldapSchemaException );
347 }
348 }
349 else
350 {
351
352 String msg = I18n.err( I18n.ERR_13755_AT_MUST_HAVE_A_SYNTAX_OID, attributeType.getName() );
353
354 LdapSchemaException ldapSchemaException = new LdapSchemaException(
355 LdapSchemaExceptionCodes.AT_SYNTAX_OR_SUPERIOR_REQUIRED, msg );
356 ldapSchemaException.setSourceObject( attributeType );
357 errorHandler.handle( LOG, msg, ldapSchemaException );
358 }
359 }
360 }
361
362
363
364
365
366
367
368
369
370 private static void buildEquality( AttributeType attributeType, SchemaErrorHandler errorHandler,
371 Registries registries )
372 {
373 String equalityOid = attributeType.getEqualityOid();
374
375
376 if ( equalityOid != null )
377 {
378 MatchingRule currentEquality = null;
379
380 try
381 {
382 currentEquality = registries.getMatchingRuleRegistry().lookup( equalityOid );
383 }
384 catch ( LdapException ne )
385 {
386
387 String msg = I18n.err( I18n.ERR_13756_CANNOT_FIND_EQUALITY_MR_OBJECT, equalityOid, attributeType.getName() );
388
389 LdapSchemaException ldapSchemaException = new LdapSchemaException(
390 LdapSchemaExceptionCodes.AT_NONEXISTENT_EQUALITY_MATCHING_RULE, msg, ne );
391 ldapSchemaException.setSourceObject( attributeType );
392 ldapSchemaException.setRelatedId( equalityOid );
393 errorHandler.handle( LOG, msg, ldapSchemaException );
394
395 return;
396 }
397
398 if ( currentEquality != null )
399 {
400 attributeType.setEquality( currentEquality );
401
402
403 attributeType.setEqualityOid( equalityOid );
404 }
405 else
406 {
407
408 String msg = I18n.err( I18n.ERR_13757_CANNOT_FIND_EQUALITY_MR_INSTANCE, equalityOid, attributeType.getName() );
409
410 LdapSchemaException ldapSchemaException = new LdapSchemaException(
411 LdapSchemaExceptionCodes.AT_NONEXISTENT_EQUALITY_MATCHING_RULE, msg );
412 ldapSchemaException.setSourceObject( attributeType );
413 ldapSchemaException.setRelatedId( equalityOid );
414 errorHandler.handle( LOG, msg, ldapSchemaException );
415 }
416 }
417 else
418 {
419 AttributeType superior = attributeType.getSuperior();
420
421
422 if ( ( superior != null ) && ( superior.getEquality() != null ) )
423 {
424 attributeType.setEquality( superior.getEquality() );
425 }
426 }
427 }
428
429
430
431
432
433
434
435
436
437 private static void buildSubstring( AttributeType attributeType, SchemaErrorHandler errorHandler,
438 Registries registries )
439 {
440 String substringOid = attributeType.getSubstringOid();
441
442
443 if ( substringOid != null )
444 {
445 MatchingRule currentSubstring = null;
446
447 try
448 {
449 currentSubstring = registries.getMatchingRuleRegistry().lookup( substringOid );
450 }
451 catch ( LdapException ne )
452 {
453
454 String msg = I18n.err( I18n.ERR_13760_CANNOT_FIND_SUBSTR_MR_OBJECT, substringOid, attributeType.getName() );
455
456 LdapSchemaException ldapSchemaException = new LdapSchemaException(
457 LdapSchemaExceptionCodes.AT_NONEXISTENT_SUBSTRING_MATCHING_RULE, msg, ne );
458 ldapSchemaException.setSourceObject( attributeType );
459 ldapSchemaException.setRelatedId( substringOid );
460 errorHandler.handle( LOG, msg, ldapSchemaException );
461
462 return;
463 }
464
465 if ( currentSubstring != null )
466 {
467 attributeType.setSubstring( currentSubstring );
468 }
469 else
470 {
471
472 String msg = I18n.err( I18n.ERR_13761_CANNOT_FIND_SUBSTR_MR_INSTANCE, substringOid, attributeType.getName() );
473
474 LdapSchemaException ldapSchemaException = new LdapSchemaException(
475 LdapSchemaExceptionCodes.AT_NONEXISTENT_SUBSTRING_MATCHING_RULE, msg );
476 ldapSchemaException.setSourceObject( attributeType );
477 ldapSchemaException.setRelatedId( substringOid );
478 errorHandler.handle( LOG, msg, ldapSchemaException );
479 }
480 }
481 else
482 {
483 AttributeType superior = attributeType.getSuperior();
484
485
486 if ( ( superior != null ) && ( superior.getSubstring() != null ) )
487 {
488 attributeType.setSubstring( superior.getSubstring() );
489 }
490 }
491 }
492
493
494
495
496
497
498
499
500
501 private static void buildOrdering( AttributeType attributeType, SchemaErrorHandler errorHandler,
502 Registries registries )
503 {
504 String orderingOid = attributeType.getOrderingOid();
505
506 if ( orderingOid != null )
507 {
508 MatchingRule currentOrdering = null;
509
510 try
511 {
512 currentOrdering = registries.getMatchingRuleRegistry().lookup( orderingOid );
513 }
514 catch ( LdapException ne )
515 {
516
517 String msg = I18n.err( I18n.ERR_13758_CANNOT_FIND_ORDERING_MR_OBJECT, orderingOid, attributeType.getName() );
518
519 LdapSchemaException ldapSchemaException = new LdapSchemaException(
520 LdapSchemaExceptionCodes.AT_NONEXISTENT_ORDERING_MATCHING_RULE, msg, ne );
521 ldapSchemaException.setSourceObject( attributeType );
522 ldapSchemaException.setRelatedId( orderingOid );
523 errorHandler.handle( LOG, msg, ldapSchemaException );
524
525 return;
526 }
527
528 if ( currentOrdering != null )
529 {
530 attributeType.setOrdering( currentOrdering );
531 }
532 else
533 {
534
535 String msg = I18n.err( I18n.ERR_13759_CANNOT_FIND_ORDERING_MR_INSTANCE, orderingOid, attributeType.getName() );
536
537 LdapSchemaException ldapSchemaException = new LdapSchemaException(
538 LdapSchemaExceptionCodes.AT_NONEXISTENT_ORDERING_MATCHING_RULE, msg );
539 ldapSchemaException.setSourceObject( attributeType );
540 ldapSchemaException.setRelatedId( orderingOid );
541 errorHandler.handle( LOG, msg, ldapSchemaException );
542 }
543 }
544 else
545 {
546 AttributeType superior = attributeType.getSuperior();
547
548
549 if ( ( superior != null ) && ( superior.getOrdering() != null ) )
550 {
551 attributeType.setOrdering( superior.getOrdering() );
552 }
553 }
554 }
555
556
557
558
559
560
561
562
563 private static void checkUsage( AttributeType attributeType, SchemaErrorHandler errorHandler )
564 {
565 AttributeType superior = attributeType.getSuperior();
566
567
568 if ( ( superior != null ) && ( attributeType.getUsage() != superior.getUsage() ) )
569 {
570
571 String msg = I18n.err( I18n.ERR_13762_AT_MUST_HAVE_SUPERIOR_USAGE, attributeType.getName() );
572
573 LdapSchemaException ldapSchemaException = new LdapSchemaException(
574 LdapSchemaExceptionCodes.AT_MUST_HAVE_SAME_USAGE_THAN_SUPERIOR, msg );
575 ldapSchemaException.setSourceObject( attributeType );
576 errorHandler.handle( LOG, msg, ldapSchemaException );
577
578 return;
579 }
580
581
582 if ( !attributeType.isUserModifiable() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
583 {
584
585 String msg = I18n.err( I18n.ERR_13763_AT_MUST_BE_USER_MODIFIABLE, attributeType.getName() );
586
587 LdapSchemaException ldapSchemaException = new LdapSchemaException(
588 LdapSchemaExceptionCodes.AT_USER_APPLICATIONS_USAGE_MUST_BE_USER_MODIFIABLE, msg );
589 ldapSchemaException.setSourceObject( attributeType );
590 errorHandler.handle( LOG, msg, ldapSchemaException );
591 }
592 }
593
594
595
596
597
598
599
600
601 private static void checkCollective( AttributeType attributeType, SchemaErrorHandler errorHandler )
602 {
603 AttributeType superior = attributeType.getSuperior();
604
605 if ( ( superior != null ) && superior.isCollective() )
606 {
607
608 attributeType.setCollective( true );
609 }
610
611 if ( attributeType.isCollective() && ( attributeType.getUsage() != UsageEnum.USER_APPLICATIONS ) )
612 {
613
614 String msg = I18n.err( I18n.ERR_13764_AT_COLLECTIVE_SHOULD_BE_USER_APP, attributeType.getName() );
615
616 LdapSchemaException ldapSchemaException = new LdapSchemaException(
617 LdapSchemaExceptionCodes.AT_COLLECTIVE_MUST_HAVE_USER_APPLICATIONS_USAGE, msg );
618 ldapSchemaException.setSourceObject( attributeType );
619 errorHandler.handle( LOG, msg, ldapSchemaException );
620 }
621
622 if ( attributeType.isCollective() && attributeType.isSingleValued() )
623 {
624
625 String msg = I18n.err( I18n.ERR_13777_COLLECTIVE_NOT_MULTI_VALUED, attributeType.getName() );
626
627 LdapSchemaException ldapSchemaException = new LdapSchemaException(
628 LdapSchemaExceptionCodes.AT_COLLECTIVE_CANNOT_BE_SINGLE_VALUED, msg );
629 ldapSchemaException.setSourceObject( attributeType );
630 errorHandler.handle( LOG, msg, ldapSchemaException );
631 }
632 }
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 public static void removeFromRegistries( AttributeType attributeType, SchemaErrorHandler errorHandler, Registries registries ) throws LdapException
648 {
649 if ( registries != null )
650 {
651 AttributeTypeRegistry attributeTypeRegistry = registries.getAttributeTypeRegistry();
652
653
654 attributeTypeRegistry.removeMappingFor( attributeType );
655
656
657 attributeTypeRegistry.unregisterDescendants( attributeType, attributeType.getSuperior() );
658
659
660
661
662
663
664
665 if ( attributeType.getEquality() != null )
666 {
667 registries.delReference( attributeType, attributeType.getEquality() );
668 }
669
670 if ( attributeType.getOrdering() != null )
671 {
672 registries.delReference( attributeType, attributeType.getOrdering() );
673 }
674
675 if ( attributeType.getSubstring() != null )
676 {
677 registries.delReference( attributeType, attributeType.getSubstring() );
678 }
679
680 if ( attributeType.getSyntax() != null )
681 {
682 registries.delReference( attributeType, attributeType.getSyntax() );
683 }
684
685 if ( attributeType.getSuperior() != null )
686 {
687 registries.delReference( attributeType, attributeType.getSuperior() );
688 }
689 }
690 }
691 }