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.schema.loader;
21
22
23 import java.lang.reflect.Constructor;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.security.AccessController;
27 import java.security.PrivilegedAction;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32
33 import org.apache.directory.api.asn1.util.Oid;
34 import org.apache.directory.api.i18n.I18n;
35 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
36 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
37 import org.apache.directory.api.ldap.model.entry.Attribute;
38 import org.apache.directory.api.ldap.model.entry.BinaryValue;
39 import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
40 import org.apache.directory.api.ldap.model.entry.Entry;
41 import org.apache.directory.api.ldap.model.entry.Value;
42 import org.apache.directory.api.ldap.model.exception.LdapException;
43 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
44 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
45 import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
46 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
47 import org.apache.directory.api.ldap.model.schema.AttributeType;
48 import org.apache.directory.api.ldap.model.schema.LdapComparator;
49 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
50 import org.apache.directory.api.ldap.model.schema.LoadableSchemaObject;
51 import org.apache.directory.api.ldap.model.schema.MatchingRule;
52 import org.apache.directory.api.ldap.model.schema.MutableAttributeType;
53 import org.apache.directory.api.ldap.model.schema.MutableMatchingRule;
54 import org.apache.directory.api.ldap.model.schema.MutableObjectClass;
55 import org.apache.directory.api.ldap.model.schema.Normalizer;
56 import org.apache.directory.api.ldap.model.schema.ObjectClass;
57 import org.apache.directory.api.ldap.model.schema.ObjectClassTypeEnum;
58 import org.apache.directory.api.ldap.model.schema.SchemaManager;
59 import org.apache.directory.api.ldap.model.schema.SchemaObject;
60 import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
61 import org.apache.directory.api.ldap.model.schema.SyntaxChecker.SCBuilder;
62 import org.apache.directory.api.ldap.model.schema.UsageEnum;
63 import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
64 import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
65 import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
66 import org.apache.directory.api.ldap.model.schema.registries.DefaultSchema;
67 import org.apache.directory.api.ldap.model.schema.registries.Registries;
68 import org.apache.directory.api.ldap.model.schema.registries.Schema;
69 import org.apache.directory.api.util.Base64;
70 import org.apache.directory.api.util.StringConstants;
71 import org.apache.directory.api.util.Strings;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
74
75
76
77
78
79
80
81 public class SchemaEntityFactory implements EntityFactory
82 {
83
84 private static final Logger LOG = LoggerFactory.getLogger( SchemaEntityFactory.class );
85
86
87 private static final List<String> EMPTY_LIST = new ArrayList<>();
88
89
90 private static final String[] EMPTY_ARRAY = new String[]
91 {};
92
93
94 private final AttributeClassLoader classLoader;
95
96
97
98
99
100 public SchemaEntityFactory()
101 {
102 this.classLoader = AccessController.doPrivileged( new PrivilegedAction<AttributeClassLoader>()
103 {
104 @Override
105 public AttributeClassLoader run()
106 {
107 return new AttributeClassLoader();
108 }
109 } );
110 }
111
112
113
114
115
116
117 private String getOid( Entry entry, String objectType, boolean strict ) throws LdapInvalidAttributeValueException
118 {
119
120 Attribute mOid = entry.get( MetaSchemaConstants.M_OID_AT );
121
122 if ( mOid == null )
123 {
124 String msg = I18n.err( I18n.ERR_10005, objectType, MetaSchemaConstants.M_OID_AT );
125 LOG.warn( msg );
126 throw new IllegalArgumentException( msg );
127 }
128
129 String oid = mOid.getString();
130
131 if ( strict && !Oid.isOid( oid ) )
132 {
133 String msg = I18n.err( I18n.ERR_10006, oid );
134 LOG.warn( msg );
135 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
136 }
137
138 return oid;
139 }
140
141
142
143
144
145
146 private String getOid( SchemaObject description, String objectType ) throws LdapInvalidAttributeValueException
147 {
148
149 String oid = description.getOid();
150
151 if ( oid == null )
152 {
153 String msg = I18n.err( I18n.ERR_10005, objectType, MetaSchemaConstants.M_OID_AT );
154 LOG.warn( msg );
155 throw new IllegalArgumentException( msg );
156 }
157
158 if ( !Oid.isOid( oid ) )
159 {
160 String msg = I18n.err( I18n.ERR_10006, oid );
161 LOG.warn( msg );
162 throw new LdapInvalidAttributeValueException( ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX, msg );
163 }
164
165 return oid;
166 }
167
168
169
170
171
172 private void checkEntry( Entry entry, String schemaEntity )
173 {
174 if ( entry == null )
175 {
176 String msg = I18n.err( I18n.ERR_10007, schemaEntity );
177 LOG.warn( msg );
178 throw new IllegalArgumentException( msg );
179 }
180 }
181
182
183
184
185
186 private void checkDescription( SchemaObject description, String schemaEntity )
187 {
188 if ( description == null )
189 {
190 String msg = I18n.err( I18n.ERR_10008, schemaEntity );
191 LOG.warn( msg );
192 throw new IllegalArgumentException( msg );
193 }
194 }
195
196
197
198
199
200
201 private Schema getSchema( String schemaName, Registries registries )
202 {
203 if ( Strings.isEmpty( schemaName ) )
204 {
205 schemaName = MetaSchemaConstants.SCHEMA_OTHER;
206 }
207
208 Schema schema = registries.getLoadedSchema( schemaName );
209
210 if ( schema == null )
211 {
212 String msg = I18n.err( I18n.ERR_10009, schemaName );
213 LOG.error( msg );
214 }
215
216 return schema;
217 }
218
219
220
221
222
223 @Override
224 public Schema getSchema( Entry entry ) throws LdapException
225 {
226 String name;
227 String owner;
228 String[] dependencies = EMPTY_ARRAY;
229 boolean isDisabled = false;
230
231 if ( entry == null )
232 {
233 throw new IllegalArgumentException( I18n.err( I18n.ERR_10010 ) );
234 }
235
236 if ( entry.get( SchemaConstants.CN_AT ) == null )
237 {
238 throw new IllegalArgumentException( I18n.err( I18n.ERR_10011 ) );
239 }
240
241 name = entry.get( SchemaConstants.CN_AT ).getString();
242
243 if ( entry.get( SchemaConstants.CREATORS_NAME_AT ) == null )
244 {
245 throw new IllegalArgumentException( I18n.err( I18n.ERR_10012, SchemaConstants.CREATORS_NAME_AT ) );
246 }
247
248 owner = entry.get( SchemaConstants.CREATORS_NAME_AT ).getString();
249
250 if ( entry.get( MetaSchemaConstants.M_DISABLED_AT ) != null )
251 {
252 String value = entry.get( MetaSchemaConstants.M_DISABLED_AT ).getString();
253 value = Strings.upperCase( value );
254 isDisabled = "TRUE".equalsIgnoreCase( value );
255 }
256
257 if ( entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT ) != null )
258 {
259 Set<String> depsSet = new HashSet<>();
260 Attribute depsAttr = entry.get( MetaSchemaConstants.M_DEPENDENCIES_AT );
261
262 for ( Value<?> value : depsAttr )
263 {
264 depsSet.add( value.getString() );
265 }
266
267 dependencies = depsSet.toArray( EMPTY_ARRAY );
268 }
269
270 return new DefaultSchema( null, name, owner, dependencies, isDisabled );
271 }
272
273
274
275
276
277 private SyntaxChecker classLoadSyntaxChecker( SchemaManager schemaManager, String oid, String className,
278 Attribute byteCode ) throws LdapException
279 {
280
281 Class<?> clazz;
282 SyntaxChecker syntaxChecker;
283 String byteCodeStr = StringConstants.EMPTY;
284
285 if ( byteCode == null )
286 {
287 try
288 {
289 clazz = Class.forName( className );
290 }
291 catch ( ClassNotFoundException cnfe )
292 {
293 LOG.error( "Cannot find the syntax checker class constructor for class {}", className );
294 throw new LdapSchemaException( "Cannot find the syntax checker class " + cnfe.getMessage() );
295 }
296 }
297 else
298 {
299 classLoader.setAttribute( byteCode );
300
301 try
302 {
303 clazz = classLoader.loadClass( className );
304 }
305 catch ( ClassNotFoundException cnfe )
306 {
307 LOG.error( "Cannot load the syntax checker class constructor for class {}", className );
308 throw new LdapSchemaException( "Cannot load the syntax checker class " + cnfe.getMessage() );
309 }
310
311
312 byteCodeStr = new String( Base64.encode( byteCode.getBytes() ) );
313 }
314
315
316 try
317 {
318 Method builder = clazz.getMethod( "builder", null );
319 syntaxChecker = ( SyntaxChecker ) ( ( SCBuilder ) builder.invoke( null, null ) ).setOid( oid ).build();
320 }
321 catch ( NoSuchMethodException nsme )
322 {
323 LOG.error( "Cannot instantiate the syntax checker class constructor for class {}", className );
324 throw new LdapSchemaException( "Cannot instantiate the syntax checker class " + nsme.getMessage() );
325 }
326 catch ( InvocationTargetException ite )
327 {
328 LOG.error( "Cannot instantiate the syntax checker class constructor for class {}", className );
329 throw new LdapSchemaException( "Cannot instantiate the syntax checker class " + ite.getMessage() );
330 }
331 catch ( IllegalAccessException iae )
332 {
333 LOG.error( "Cannot access the syntax checker class constructor for class {}", className );
334 throw new LdapSchemaException( "Cannot access the syntax checker class constructor " + iae.getMessage() );
335 }
336
337
338 syntaxChecker.setBytecode( byteCodeStr );
339 syntaxChecker.setFqcn( className );
340
341
342 syntaxChecker.setSchemaManager( schemaManager );
343
344 return syntaxChecker;
345 }
346
347
348
349
350
351 @Override
352 public SyntaxChecker getSyntaxChecker( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
353 String schemaName ) throws LdapException
354 {
355 checkEntry( entry, SchemaConstants.SYNTAX_CHECKER );
356
357
358 String oid = getOid( entry, SchemaConstants.SYNTAX_CHECKER, schemaManager.isStrict() );
359
360
361 if ( !schemaManager.isSchemaLoaded( schemaName ) )
362 {
363
364 String msg = I18n.err( I18n.ERR_10013, entry.getDn().getName(), schemaName );
365 LOG.warn( msg );
366 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
367 }
368
369 Schema schema = getSchema( schemaName, targetRegistries );
370
371 if ( schema == null )
372 {
373
374 String msg = I18n.err( I18n.ERR_10014, entry.getDn().getName(), schemaName );
375 LOG.info( msg );
376 schema = schemaManager.getLoadedSchema( schemaName );
377 }
378
379
380 String className = getFqcn( entry, SchemaConstants.SYNTAX_CHECKER );
381
382
383 Attribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
384
385 try
386 {
387
388 SyntaxChecker syntaxChecker = classLoadSyntaxChecker( schemaManager, oid, className, byteCode );
389
390
391 setSchemaObjectProperties( syntaxChecker, entry, schema );
392
393
394 return syntaxChecker;
395 }
396 catch ( Exception e )
397 {
398 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getMessage(), e );
399 }
400 }
401
402
403
404
405
406 @Override
407 public SyntaxChecker getSyntaxChecker( SchemaManager schemaManager,
408 SyntaxCheckerDescription syntaxCheckerDescription, Registries targetRegistries, String schemaName )
409 throws LdapException
410 {
411 checkDescription( syntaxCheckerDescription, SchemaConstants.SYNTAX_CHECKER );
412
413
414 String oid = getOid( syntaxCheckerDescription, SchemaConstants.SYNTAX_CHECKER );
415
416
417 Schema schema = getSchema( schemaName, targetRegistries );
418
419 if ( schema == null )
420 {
421
422 String msg = I18n.err( I18n.ERR_10013, syntaxCheckerDescription.getName(), schemaName );
423 LOG.warn( msg );
424 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
425 }
426
427
428 String fqcn = getFqcn( syntaxCheckerDescription, SchemaConstants.SYNTAX_CHECKER );
429
430
431 Attribute byteCode = getByteCode( syntaxCheckerDescription, SchemaConstants.SYNTAX_CHECKER );
432
433
434 SyntaxChecker syntaxChecker = classLoadSyntaxChecker( schemaManager, oid, fqcn, byteCode );
435
436
437 setSchemaObjectProperties( syntaxChecker, syntaxCheckerDescription, schema );
438
439 return syntaxChecker;
440 }
441
442
443
444
445
446 private LdapComparator<?> classLoadComparator( SchemaManager schemaManager, String oid, String className,
447 Attribute byteCode ) throws LdapException
448 {
449
450 LdapComparator<?> comparator;
451 Class<?> clazz;
452 String byteCodeStr = StringConstants.EMPTY;
453
454 if ( byteCode == null )
455 {
456 try
457 {
458 clazz = Class.forName( className );
459 }
460 catch ( ClassNotFoundException cnfe )
461 {
462 LOG.error( "Cannot find the comparator class constructor for class {}", className );
463 throw new LdapSchemaException( "Cannot find the comparator class " + cnfe.getMessage() );
464 }
465 }
466 else
467 {
468 classLoader.setAttribute( byteCode );
469
470 try
471 {
472 clazz = classLoader.loadClass( className );
473 }
474 catch ( ClassNotFoundException cnfe )
475 {
476 LOG.error( "Cannot load the comparator class constructor for class {}", className );
477 throw new LdapSchemaException( "Cannot load the comparator class " + cnfe.getMessage() );
478 }
479
480 byteCodeStr = new String( Base64.encode( byteCode.getBytes() ) );
481 }
482
483
484
485 try
486 {
487 Constructor<?> constructor = clazz.getConstructor( new Class[]
488 { String.class } );
489
490 try
491 {
492 comparator = ( LdapComparator<?> ) constructor.newInstance( new Object[]
493 { oid } );
494 }
495 catch ( InvocationTargetException ite )
496 {
497 LOG.error( "Cannot invoke the comparator class constructor for class {}", className );
498 throw new LdapSchemaException( "Cannot invoke the comparator class " + ite.getMessage() );
499 }
500 catch ( InstantiationException ie )
501 {
502 LOG.error( "Cannot instanciate the comparator class constructor for class {}", className );
503 throw new LdapSchemaException( "Cannot instanciate the comparator class " + ie.getMessage() );
504 }
505 catch ( IllegalAccessException ie )
506 {
507 LOG.error( "Cannot access the comparator class constructor for class {}", className );
508 throw new LdapSchemaException( "Cannot access the comparator class " + ie.getMessage() );
509 }
510 }
511 catch ( NoSuchMethodException nsme )
512 {
513
514
515
516 try
517 {
518 clazz.getConstructor();
519 }
520 catch ( NoSuchMethodException nsme2 )
521 {
522 LOG.error( "Cannot find the comparator class constructor method for class {}", className );
523 throw new LdapSchemaException( "Cannot find the comparator class constructor method" + nsme2.getMessage() );
524 }
525
526 try
527 {
528 comparator = ( LdapComparator<?> ) clazz.newInstance();
529 }
530 catch ( InstantiationException ie )
531 {
532 LOG.error( "Cannot instantiate the comparator class constructor for class {}", className );
533 throw new LdapSchemaException( "Cannot instantiate the comparator class " + ie.getMessage() );
534 }
535 catch ( IllegalAccessException iae )
536 {
537 LOG.error( "Cannot access the comparator class constructor for class {}", className );
538 throw new LdapSchemaException( "Cannot access the comparator class constructor " + iae.getMessage() );
539 }
540
541 if ( !comparator.getOid().equals( oid ) )
542 {
543 String msg = I18n.err( I18n.ERR_10015, oid, comparator.getOid() );
544 throw new LdapInvalidAttributeValueException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg, nsme );
545 }
546 }
547
548
549 comparator.setBytecode( byteCodeStr );
550 comparator.setFqcn( className );
551
552
553 comparator.setSchemaManager( schemaManager );
554
555 return comparator;
556 }
557
558
559
560
561
562 @Override
563 public LdapComparator<?> getLdapComparator( SchemaManager schemaManager,
564 LdapComparatorDescription comparatorDescription, Registries targetRegistries, String schemaName )
565 throws LdapException
566 {
567 checkDescription( comparatorDescription, SchemaConstants.COMPARATOR );
568
569
570 String oid = getOid( comparatorDescription, SchemaConstants.COMPARATOR );
571
572
573 Schema schema = getSchema( schemaName, targetRegistries );
574
575 if ( schema == null )
576 {
577
578 String msg = I18n.err( I18n.ERR_10016, comparatorDescription.getName(), schemaName );
579 LOG.warn( msg );
580 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
581 }
582
583
584 String fqcn = getFqcn( comparatorDescription, SchemaConstants.COMPARATOR );
585
586
587 Attribute byteCode = getByteCode( comparatorDescription, SchemaConstants.COMPARATOR );
588
589
590 LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode );
591
592
593 setSchemaObjectProperties( comparator, comparatorDescription, schema );
594
595 return comparator;
596 }
597
598
599
600
601
602 @Override
603 public LdapComparator<?> getLdapComparator( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
604 String schemaName ) throws LdapException
605 {
606 checkEntry( entry, SchemaConstants.COMPARATOR );
607
608
609 String oid = getOid( entry, SchemaConstants.COMPARATOR, schemaManager.isStrict() );
610
611
612 if ( !schemaManager.isSchemaLoaded( schemaName ) )
613 {
614
615 String msg = I18n.err( I18n.ERR_10016, entry.getDn().getName(), schemaName );
616 LOG.warn( msg );
617 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
618 }
619
620 Schema schema = getSchema( schemaName, targetRegistries );
621
622 if ( schema == null )
623 {
624
625 String msg = I18n.err( I18n.ERR_10017, entry.getDn().getName(), schemaName );
626 LOG.info( msg );
627 schema = schemaManager.getLoadedSchema( schemaName );
628 }
629
630
631 String fqcn = getFqcn( entry, SchemaConstants.COMPARATOR );
632
633
634 Attribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
635
636 try
637 {
638
639 LdapComparator<?> comparator = classLoadComparator( schemaManager, oid, fqcn, byteCode );
640
641
642 setSchemaObjectProperties( comparator, entry, schema );
643
644
645 return comparator;
646 }
647 catch ( Exception e )
648 {
649 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getMessage(), e );
650 }
651 }
652
653
654
655
656
657 private Normalizer classLoadNormalizer( SchemaManager schemaManager, String oid, String className,
658 Attribute byteCode ) throws LdapException
659 {
660
661 Class<?> clazz;
662 Normalizer normalizer;
663 String byteCodeStr = StringConstants.EMPTY;
664
665 if ( byteCode == null )
666 {
667 try
668 {
669 clazz = Class.forName( className );
670 }
671 catch ( ClassNotFoundException cnfe )
672 {
673 LOG.error( "Cannot find the normalizer class constructor for class {}", className );
674 throw new LdapSchemaException( "Cannot find the normalizer class " + cnfe.getMessage() );
675 }
676 }
677 else
678 {
679 classLoader.setAttribute( byteCode );
680
681 try
682 {
683 clazz = classLoader.loadClass( className );
684 }
685 catch ( ClassNotFoundException cnfe )
686 {
687 LOG.error( "Cannot load the normalizer class constructor for class {}", className );
688 throw new LdapSchemaException( "Cannot load the normalizer class " + cnfe.getMessage() );
689 }
690
691 byteCodeStr = new String( Base64.encode( byteCode.getBytes() ) );
692 }
693
694
695 try
696 {
697 normalizer = ( Normalizer ) clazz.newInstance();
698 }
699 catch ( InstantiationException ie )
700 {
701 LOG.error( "Cannot instantiate the normalizer class constructor for class {}", className );
702 throw new LdapSchemaException( "Cannot instantiate the normalizer class " + ie.getMessage() );
703 }
704 catch ( IllegalAccessException iae )
705 {
706 LOG.error( "Cannot access the normalizer class constructor for class {}", className );
707 throw new LdapSchemaException( "Cannot access the normalizer class constructor " + iae.getMessage() );
708 }
709
710
711 normalizer.setBytecode( byteCodeStr );
712 normalizer.setFqcn( className );
713
714
715 normalizer.setOid( oid );
716
717
718 normalizer.setSchemaManager( schemaManager );
719
720 return normalizer;
721 }
722
723
724
725
726
727 @Override
728 public Normalizer getNormalizer( SchemaManager schemaManager, NormalizerDescription normalizerDescription,
729 Registries targetRegistries, String schemaName ) throws LdapException
730 {
731 checkDescription( normalizerDescription, SchemaConstants.NORMALIZER );
732
733
734 String oid = getOid( normalizerDescription, SchemaConstants.NORMALIZER );
735
736
737 Schema schema = getSchema( schemaName, targetRegistries );
738
739 if ( schema == null )
740 {
741
742 String msg = I18n.err( I18n.ERR_10018, normalizerDescription.getName(), schemaName );
743 LOG.warn( msg );
744 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
745 }
746
747
748 String fqcn = getFqcn( normalizerDescription, SchemaConstants.NORMALIZER );
749
750
751 Attribute byteCode = getByteCode( normalizerDescription, SchemaConstants.NORMALIZER );
752
753
754 Normalizer normalizer = classLoadNormalizer( schemaManager, oid, fqcn, byteCode );
755
756
757 setSchemaObjectProperties( normalizer, normalizerDescription, schema );
758
759 return normalizer;
760 }
761
762
763
764
765
766 @Override
767 public Normalizer getNormalizer( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
768 String schemaName ) throws LdapException
769 {
770 checkEntry( entry, SchemaConstants.NORMALIZER );
771
772
773 String oid = getOid( entry, SchemaConstants.NORMALIZER, schemaManager.isStrict() );
774
775
776 if ( !schemaManager.isSchemaLoaded( schemaName ) )
777 {
778
779 String msg = I18n.err( I18n.ERR_10018, entry.getDn().getName(), schemaName );
780 LOG.warn( msg );
781 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
782 }
783
784 Schema schema = getSchema( schemaName, targetRegistries );
785
786 if ( schema == null )
787 {
788
789 String msg = I18n.err( I18n.ERR_10019, entry.getDn().getName(), schemaName );
790 LOG.info( msg );
791 schema = schemaManager.getLoadedSchema( schemaName );
792 }
793
794
795 String className = getFqcn( entry, SchemaConstants.NORMALIZER );
796
797
798 Attribute byteCode = entry.get( MetaSchemaConstants.M_BYTECODE_AT );
799
800 try
801 {
802
803 Normalizer normalizer = classLoadNormalizer( schemaManager, oid, className, byteCode );
804
805
806 setSchemaObjectProperties( normalizer, entry, schema );
807
808
809 return normalizer;
810 }
811 catch ( Exception e )
812 {
813 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, e.getMessage(), e );
814 }
815 }
816
817
818
819
820
821
822
823 @Override
824 public LdapSyntax getSyntax( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
825 String schemaName ) throws LdapInvalidAttributeValueException, LdapUnwillingToPerformException
826 {
827 checkEntry( entry, SchemaConstants.SYNTAX );
828
829
830 String oid = getOid( entry, SchemaConstants.SYNTAX, schemaManager.isStrict() );
831
832
833 if ( !schemaManager.isSchemaLoaded( schemaName ) )
834 {
835
836 String msg = I18n.err( I18n.ERR_10020, entry.getDn().getName(), schemaName );
837 LOG.warn( msg );
838 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
839 }
840
841 Schema schema = getSchema( schemaName, targetRegistries );
842
843 if ( schema == null )
844 {
845
846 String msg = I18n.err( I18n.ERR_10021, entry.getDn().getName(), schemaName );
847 LOG.info( msg );
848 schema = schemaManager.getLoadedSchema( schemaName );
849 }
850
851
852 LdapSyntax syntax = new LdapSyntax( oid );
853
854
855 setSchemaObjectProperties( syntax, entry, schema );
856
857 return syntax;
858 }
859
860
861
862
863
864
865
866 @Override
867 public MatchingRule getMatchingRule( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
868 String schemaName ) throws LdapUnwillingToPerformException, LdapInvalidAttributeValueException
869 {
870 checkEntry( entry, SchemaConstants.MATCHING_RULE );
871
872
873 String oid = getOid( entry, SchemaConstants.MATCHING_RULE, schemaManager.isStrict() );
874
875
876 if ( !schemaManager.isSchemaLoaded( schemaName ) )
877 {
878
879 String msg = I18n.err( I18n.ERR_10022, entry.getDn().getName(), schemaName );
880 LOG.warn( msg );
881 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
882 }
883
884 Schema schema = getSchema( schemaName, targetRegistries );
885
886 if ( schema == null )
887 {
888
889 String msg = I18n.err( I18n.ERR_10023, entry.getDn().getName(), schemaName );
890 LOG.info( msg );
891 schema = schemaManager.getLoadedSchema( schemaName );
892 }
893
894 MutableMatchingRule matchingRule = new MutableMatchingRule( oid );
895
896
897 Attribute mSyntax = entry.get( MetaSchemaConstants.M_SYNTAX_AT );
898
899 if ( mSyntax != null )
900 {
901 matchingRule.setSyntaxOid( mSyntax.getString() );
902 }
903
904
905
906
907
908 setSchemaObjectProperties( matchingRule, entry, schema );
909
910 return matchingRule;
911 }
912
913
914
915
916
917 private List<String> getStrings( Attribute attr )
918 {
919 if ( attr == null )
920 {
921 return EMPTY_LIST;
922 }
923
924 List<String> strings = new ArrayList<>( attr.size() );
925
926 for ( Value<?> value : attr )
927 {
928 strings.add( value.getString() );
929 }
930
931 return strings;
932 }
933
934
935
936
937
938 @Override
939 public ObjectClass getObjectClass( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
940 String schemaName ) throws LdapException
941 {
942 checkEntry( entry, SchemaConstants.OBJECT_CLASS );
943
944
945 String oid = getOid( entry, SchemaConstants.OBJECT_CLASS, schemaManager.isStrict() );
946
947
948 if ( !schemaManager.isSchemaLoaded( schemaName ) )
949 {
950
951 String msg = I18n.err( I18n.ERR_10024, entry.getDn().getName(), schemaName );
952 LOG.warn( msg );
953 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
954 }
955
956 Schema schema = getSchema( schemaName, targetRegistries );
957
958 if ( schema == null )
959 {
960
961 String msg = I18n.err( I18n.ERR_10025, entry.getDn().getName(), schemaName );
962 LOG.info( msg );
963 schema = schemaManager.getLoadedSchema( schemaName );
964 }
965
966
967 MutableObjectClass oc = new MutableObjectClass( oid );
968
969
970 Attribute mSuperiors = entry.get( MetaSchemaConstants.M_SUP_OBJECT_CLASS_AT );
971
972 if ( mSuperiors != null )
973 {
974 oc.setSuperiorOids( getStrings( mSuperiors ) );
975 }
976
977
978 Attribute mMay = entry.get( MetaSchemaConstants.M_MAY_AT );
979
980 if ( mMay != null )
981 {
982 oc.setMayAttributeTypeOids( getStrings( mMay ) );
983 }
984
985
986 Attribute mMust = entry.get( MetaSchemaConstants.M_MUST_AT );
987
988 if ( mMust != null )
989 {
990 oc.setMustAttributeTypeOids( getStrings( mMust ) );
991 }
992
993
994 Attribute mTypeObjectClass = entry.get( MetaSchemaConstants.M_TYPE_OBJECT_CLASS_AT );
995
996 if ( mTypeObjectClass != null )
997 {
998 String type = mTypeObjectClass.getString();
999 oc.setType( ObjectClassTypeEnum.getClassType( type ) );
1000 }
1001
1002
1003 setSchemaObjectProperties( oc, entry, schema );
1004
1005 return oc;
1006 }
1007
1008
1009
1010
1011
1012
1013
1014 @Override
1015 public AttributeType getAttributeType( SchemaManager schemaManager, Entry entry, Registries targetRegistries,
1016 String schemaName ) throws LdapInvalidAttributeValueException, LdapUnwillingToPerformException
1017 {
1018 checkEntry( entry, SchemaConstants.ATTRIBUTE_TYPE );
1019
1020
1021 String oid = getOid( entry, SchemaConstants.ATTRIBUTE_TYPE, schemaManager.isStrict() );
1022
1023
1024 if ( !schemaManager.isSchemaLoaded( schemaName ) )
1025 {
1026
1027 String msg = I18n.err( I18n.ERR_10026, entry.getDn().getName(), schemaName );
1028 LOG.warn( msg );
1029 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
1030 }
1031
1032 Schema schema = getSchema( schemaName, targetRegistries );
1033
1034 if ( schema == null )
1035 {
1036
1037 String msg = I18n.err( I18n.ERR_10027, entry.getDn().getName(), schemaName );
1038 LOG.info( msg );
1039 schema = schemaManager.getLoadedSchema( schemaName );
1040 }
1041
1042
1043 MutableAttributeType attributeType = new MutableAttributeType( oid );
1044
1045 if ( schemaManager.isRelaxed() )
1046 {
1047 attributeType.setRelaxed( true );
1048 }
1049
1050
1051 Attribute mSyntax = entry.get( MetaSchemaConstants.M_SYNTAX_AT );
1052
1053 if ( ( mSyntax != null ) && ( mSyntax.get() != null ) )
1054 {
1055 attributeType.setSyntaxOid( mSyntax.getString() );
1056 }
1057
1058
1059 Attribute mSyntaxLength = entry.get( MetaSchemaConstants.M_LENGTH_AT );
1060
1061 if ( mSyntaxLength != null )
1062 {
1063 attributeType.setSyntaxLength( Integer.parseInt( mSyntaxLength.getString() ) );
1064 }
1065
1066
1067 Attribute mEquality = entry.get( MetaSchemaConstants.M_EQUALITY_AT );
1068
1069 if ( mEquality != null )
1070 {
1071 attributeType.setEqualityOid( mEquality.getString() );
1072 }
1073
1074
1075 Attribute mOrdering = entry.get( MetaSchemaConstants.M_ORDERING_AT );
1076
1077 if ( mOrdering != null )
1078 {
1079 attributeType.setOrderingOid( mOrdering.getString() );
1080 }
1081
1082
1083 Attribute mSubstr = entry.get( MetaSchemaConstants.M_SUBSTR_AT );
1084
1085 if ( mSubstr != null )
1086 {
1087 attributeType.setSubstringOid( mSubstr.getString() );
1088 }
1089
1090 Attribute mSupAttributeType = entry.get( MetaSchemaConstants.M_SUP_ATTRIBUTE_TYPE_AT );
1091
1092
1093 if ( mSupAttributeType != null )
1094 {
1095 attributeType.setSuperiorOid( mSupAttributeType.getString() );
1096 }
1097
1098
1099 Attribute mCollective = entry.get( MetaSchemaConstants.M_COLLECTIVE_AT );
1100
1101 if ( mCollective != null )
1102 {
1103 String val = mCollective.getString();
1104 attributeType.setCollective( "TRUE".equalsIgnoreCase( val ) );
1105 }
1106
1107
1108 Attribute mSingleValued = entry.get( MetaSchemaConstants.M_SINGLE_VALUE_AT );
1109
1110 if ( mSingleValued != null )
1111 {
1112 String val = mSingleValued.getString();
1113 attributeType.setSingleValued( "TRUE".equalsIgnoreCase( val ) );
1114 }
1115
1116
1117 Attribute mNoUserModification = entry.get( MetaSchemaConstants.M_NO_USER_MODIFICATION_AT );
1118
1119 if ( mNoUserModification != null )
1120 {
1121 String val = mNoUserModification.getString();
1122 attributeType.setUserModifiable( !"TRUE".equalsIgnoreCase( val ) );
1123 }
1124
1125
1126 Attribute mUsage = entry.get( MetaSchemaConstants.M_USAGE_AT );
1127
1128 if ( mUsage != null )
1129 {
1130 attributeType.setUsage( UsageEnum.getUsage( mUsage.getString() ) );
1131 }
1132
1133
1134 setSchemaObjectProperties( attributeType, entry, schema );
1135
1136 return attributeType;
1137 }
1138
1139
1140
1141
1142
1143
1144 private String getFqcn( Entry entry, String objectType ) throws LdapInvalidAttributeValueException
1145 {
1146
1147 Attribute mFqcn = entry.get( MetaSchemaConstants.M_FQCN_AT );
1148
1149 if ( mFqcn == null )
1150 {
1151 String msg = I18n.err( I18n.ERR_10028, objectType, MetaSchemaConstants.M_FQCN_AT );
1152 LOG.warn( msg );
1153 throw new IllegalArgumentException( msg );
1154 }
1155
1156 return mFqcn.getString();
1157 }
1158
1159
1160
1161
1162
1163 private String getFqcn( LoadableSchemaObject description, String objectType )
1164 {
1165
1166 String mFqcn = description.getFqcn();
1167
1168 if ( mFqcn == null )
1169 {
1170 String msg = I18n.err( I18n.ERR_10028, objectType, MetaSchemaConstants.M_FQCN_AT );
1171 LOG.warn( msg );
1172 throw new IllegalArgumentException( msg );
1173 }
1174
1175 return mFqcn;
1176 }
1177
1178
1179
1180
1181
1182 private Attribute getByteCode( LoadableSchemaObject description, String objectType )
1183 {
1184 String byteCodeString = description.getBytecode();
1185
1186 if ( byteCodeString == null )
1187 {
1188 String msg = I18n.err( I18n.ERR_10028, objectType, MetaSchemaConstants.M_BYTECODE_AT );
1189 LOG.warn( msg );
1190 throw new IllegalArgumentException( msg );
1191 }
1192
1193 byte[] bytecode = Base64.decode( byteCodeString.toCharArray() );
1194
1195 return new DefaultAttribute( MetaSchemaConstants.M_BYTECODE_AT, bytecode );
1196 }
1197
1198
1199
1200
1201
1202 private String getStringValue( Attribute attribute )
1203 {
1204 Value<?> value = attribute.get();
1205
1206 if ( value instanceof BinaryValue )
1207 {
1208
1209 return Strings.utf8ToString( value.getBytes() );
1210 }
1211 else
1212 {
1213 return value.getString();
1214 }
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230 private void setSchemaObjectProperties( SchemaObject schemaObject, Entry entry, Schema schema )
1231 throws LdapInvalidAttributeValueException
1232 {
1233
1234 Attribute mObsolete = entry.get( MetaSchemaConstants.M_OBSOLETE_AT );
1235
1236 if ( mObsolete != null )
1237 {
1238 String val = mObsolete.getString();
1239 schemaObject.setObsolete( "TRUE".equalsIgnoreCase( val ) );
1240 }
1241
1242
1243 Attribute mDescription = entry.get( MetaSchemaConstants.M_DESCRIPTION_AT );
1244
1245 if ( mDescription != null )
1246 {
1247 schemaObject.setDescription( getStringValue( mDescription ) );
1248 }
1249
1250
1251 Attribute names = entry.get( MetaSchemaConstants.M_NAME_AT );
1252
1253 if ( names != null )
1254 {
1255 List<String> values = new ArrayList<>();
1256
1257 for ( Value<?> name : names )
1258 {
1259 values.add( name.getString() );
1260 }
1261
1262 schemaObject.setNames( values );
1263 }
1264
1265
1266 Attribute mDisabled = entry.get( MetaSchemaConstants.M_DISABLED_AT );
1267
1268
1269
1270 if ( mDisabled != null )
1271 {
1272 String val = mDisabled.getString();
1273 schemaObject.setEnabled( !"TRUE".equalsIgnoreCase( val ) );
1274 }
1275 else
1276 {
1277 schemaObject.setEnabled( schema.isEnabled() );
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 schemaObject.setSchemaName( schema.getSchemaName() );
1293
1294
1295
1296 Attribute xSchema = entry.get( MetaSchemaConstants.X_SCHEMA_AT );
1297
1298 if ( xSchema != null )
1299 {
1300 String schemaName = xSchema.getString();
1301
1302 if ( !schema.getSchemaName().equalsIgnoreCase( schemaName ) )
1303 {
1304 LOG.warn( "Schema (" + schema.getSchemaName() + ") and X-SCHEMA ("
1305 + schemaName + ") are different : " + entry );
1306 }
1307
1308 schemaObject.addExtension( MetaSchemaConstants.X_SCHEMA_AT, schemaName );
1309 }
1310
1311
1312 Attribute xNotHumanReadable = entry.get( MetaSchemaConstants.X_NOT_HUMAN_READABLE_AT );
1313
1314 if ( xNotHumanReadable != null )
1315 {
1316 String value = xNotHumanReadable.getString();
1317
1318 schemaObject.addExtension( MetaSchemaConstants.X_NOT_HUMAN_READABLE_AT, value );
1319 }
1320
1321
1322 Attribute xReadOnly = entry.get( MetaSchemaConstants.X_READ_ONLY_AT );
1323
1324 if ( xReadOnly != null )
1325 {
1326 String value = xReadOnly.getString();
1327
1328 schemaObject.addExtension( MetaSchemaConstants.X_READ_ONLY_AT, value );
1329 }
1330 }
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344 private void setSchemaObjectProperties( SchemaObject schemaObject, SchemaObject description, Schema schema )
1345 {
1346
1347 schemaObject.setObsolete( description.isObsolete() );
1348
1349
1350 schemaObject.setDescription( description.getDescription() );
1351
1352
1353 schemaObject.setNames( description.getNames() );
1354
1355
1356
1357 schemaObject.setEnabled( schema.isEnabled() );
1358
1359
1360
1361
1362 schemaObject.setReadOnly( false );
1363
1364
1365 schemaObject.setSpecification( description.getSpecification() );
1366
1367
1368 schemaObject.setSchemaName( schema.getSchemaName() );
1369
1370
1371 schemaObject.setExtensions( description.getExtensions() );
1372 }
1373 }