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;
21
22
23 import java.util.List;
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public final class SchemaObjectRenderer
42 {
43
44
45
46
47 public static final SchemaObjectRenderer SUBSCHEMA_SUBENTRY_RENDERER = new SchemaObjectRenderer(
48 Style.SUBSCHEMA_SUBENTRY_WITH_SCHEMA_NAME );
49
50
51
52
53
54 public static final SchemaObjectRenderer OPEN_LDAP_SCHEMA_RENDERER = new SchemaObjectRenderer(
55 Style.OPENLDAP_SCHEMA_PRETTY_PRINTED );
56
57 private enum Style
58 {
59 SUBSCHEMA_SUBENTRY_WITH_SCHEMA_NAME(false, false, true),
60
61 OPENLDAP_SCHEMA_PRETTY_PRINTED(true, true, false);
62
63 final boolean startWithSchemaType;
64 final boolean prettyPrint;
65 final boolean printSchemaName;
66
67
68 Style( boolean startWithSchemaType, boolean prettyPrint, boolean printSchemaName )
69 {
70 this.startWithSchemaType = startWithSchemaType;
71 this.prettyPrint = prettyPrint;
72 this.printSchemaName = printSchemaName;
73 }
74 }
75
76 private final Style style;
77
78
79 private SchemaObjectRenderer( Style style )
80 {
81 this.style = style;
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public String render( ObjectClass oc )
127 {
128 StringBuilder buf = renderStartOidNamesDescObsolete( oc, "objectclass" );
129
130 renderOids( buf, "SUP", oc.getSuperiorOids() );
131
132 if ( oc.getType() != null )
133 {
134 prettyPrintIndent( buf );
135 buf.append( oc.getType() );
136 prettyPrintNewLine( buf );
137 }
138
139 renderOids( buf, "MUST", oc.getMustAttributeTypeOids() );
140
141 renderOids( buf, "MAY", oc.getMayAttributeTypeOids() );
142
143 renderXSchemaName( oc, buf );
144
145
146
147
148 renderClose( buf );
149
150 return buf.toString();
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 public String render( AttributeType at )
211 {
212 StringBuilder buf = renderStartOidNamesDescObsolete( at, "attributetype" );
213
214
215
216
217
218
219 if ( at.getSuperior() != null )
220 {
221 prettyPrintIndent( buf );
222 buf.append( "SUP " ).append( at.getSuperior().getName() );
223 prettyPrintNewLine( buf );
224 }
225 else if ( at.getSuperiorOid() != null )
226 {
227 prettyPrintIndent( buf );
228 buf.append( "SUP " ).append( at.getSuperiorOid() );
229 prettyPrintNewLine( buf );
230 }
231
232 if ( at.getEquality() != null )
233 {
234 prettyPrintIndent( buf );
235 buf.append( "EQUALITY " ).append( at.getEquality().getName() );
236 prettyPrintNewLine( buf );
237 }
238 else if ( at.getEqualityOid() != null )
239 {
240 prettyPrintIndent( buf );
241 buf.append( "EQUALITY " ).append( at.getEqualityOid() );
242 prettyPrintNewLine( buf );
243 }
244
245 if ( at.getOrdering() != null )
246 {
247 prettyPrintIndent( buf );
248 buf.append( "ORDERING " ).append( at.getOrdering().getName() );
249 prettyPrintNewLine( buf );
250 }
251 else if ( at.getOrderingOid() != null )
252 {
253 prettyPrintIndent( buf );
254 buf.append( "ORDERING " ).append( at.getOrderingOid() );
255 prettyPrintNewLine( buf );
256 }
257
258 if ( at.getSubstring() != null )
259 {
260 prettyPrintIndent( buf );
261 buf.append( "SUBSTR " ).append( at.getSubstring().getName() );
262 prettyPrintNewLine( buf );
263 }
264 else if ( at.getSubstringOid() != null )
265 {
266 prettyPrintIndent( buf );
267 buf.append( "SUBSTR " ).append( at.getSubstringOid() );
268 prettyPrintNewLine( buf );
269 }
270
271 if ( at.getSyntaxOid() != null )
272 {
273 prettyPrintIndent( buf );
274 buf.append( "SYNTAX " ).append( at.getSyntaxOid() );
275
276 if ( at.getSyntaxLength() > 0 )
277 {
278 buf.append( "{" ).append( at.getSyntaxLength() ).append( "}" );
279 }
280 prettyPrintNewLine( buf );
281 }
282
283 if ( at.isSingleValued() )
284 {
285 prettyPrintIndent( buf );
286 buf.append( "SINGLE-VALUE" );
287 prettyPrintNewLine( buf );
288 }
289
290 if ( at.isCollective() )
291 {
292 prettyPrintIndent( buf );
293 buf.append( "COLLECTIVE" );
294 prettyPrintNewLine( buf );
295 }
296
297 if ( !at.isUserModifiable() )
298 {
299 prettyPrintIndent( buf );
300 buf.append( "NO-USER-MODIFICATION" );
301 prettyPrintNewLine( buf );
302 }
303
304 if ( at.getUsage() != null )
305 {
306 prettyPrintIndent( buf );
307 buf.append( "USAGE " ).append( UsageEnum.render( at.getUsage() ) );
308 prettyPrintNewLine( buf );
309 }
310
311 renderXSchemaName( at, buf );
312
313
314
315
316 renderClose( buf );
317
318 return buf.toString();
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 public String render( MatchingRule mr )
365 {
366 StringBuilder buf = renderStartOidNamesDescObsolete( mr, "matchingrule" );
367
368 prettyPrintIndent( buf );
369 buf.append( "SYNTAX " ).append( mr.getSyntaxOid() );
370 prettyPrintNewLine( buf );
371
372 renderXSchemaName( mr, buf );
373
374
375
376
377 renderClose( buf );
378
379 return buf.toString();
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 public String render( LdapSyntax syntax )
407 {
408 StringBuilder buf = new StringBuilder();
409
410 if ( style.startWithSchemaType )
411 {
412 buf.append( "ldapsyntax " );
413 }
414
415 buf.append( "( " ).append( syntax.getOid() );
416 prettyPrintNewLine( buf );
417
418 renderDescription( syntax, buf );
419
420 renderXSchemaName( syntax, buf );
421
422 prettyPrintIndent( buf );
423 if ( syntax.isHumanReadable() )
424 {
425 buf.append( "X-NOT-HUMAN-READABLE 'false'" );
426 }
427 else
428 {
429 buf.append( "X-NOT-HUMAN-READABLE 'true'" );
430 }
431 prettyPrintNewLine( buf );
432
433
434
435
436 renderClose( buf );
437
438 return buf.toString();
439 }
440
441
442
443
444
445
446
447
448
449 public String render( MatchingRuleUse mru )
450 {
451 StringBuilder buf = renderStartOidNamesDescObsolete( mru, "matchingruleuse" );
452
453 List<String> applies = mru.getApplicableAttributeOids();
454
455 if ( ( applies != null ) && !applies.isEmpty() )
456 {
457 prettyPrintIndent( buf );
458 buf.append( "APPLIES " );
459 renderOids( buf, applies );
460 prettyPrintNewLine( buf );
461 }
462
463 renderXSchemaName( mru, buf );
464
465
466
467
468 renderClose( buf );
469
470 return buf.toString();
471 }
472
473
474
475
476
477
478
479
480
481 public String render( DitContentRule dcr )
482 {
483 StringBuilder buf = renderStartOidNamesDescObsolete( dcr, "ditcontentrule" );
484
485 renderOids( buf, "AUX", dcr.getAuxObjectClassOids() );
486
487 renderOids( buf, "MUST", dcr.getMustAttributeTypeOids() );
488
489 renderOids( buf, "MAY", dcr.getMayAttributeTypeOids() );
490
491 renderOids( buf, "NOT", dcr.getNotAttributeTypeOids() );
492
493 renderXSchemaName( dcr, buf );
494
495
496
497
498 renderClose( buf );
499
500 return buf.toString();
501 }
502
503
504
505
506
507
508
509
510 public String render( DitStructureRule dsr )
511 {
512 StringBuilder buf = new StringBuilder();
513
514 if ( style.startWithSchemaType )
515 {
516 buf.append( "ditstructurerule " );
517 }
518
519 buf.append( "( " ).append( dsr.getRuleId() );
520
521 renderNames( dsr, buf );
522
523 renderDescription( dsr, buf );
524
525 renderObsolete( dsr, buf );
526
527 prettyPrintIndent( buf );
528 buf.append( "FORM " ).append( dsr.getForm() );
529 prettyPrintNewLine( buf );
530
531 renderRuleIds( buf, dsr.getSuperRules() );
532
533 renderXSchemaName( dsr, buf );
534
535
536
537
538 renderClose( buf );
539
540 return buf.toString();
541 }
542
543
544
545
546
547
548
549
550
551 public String render( NameForm nf )
552 {
553 StringBuilder buf = renderStartOidNamesDescObsolete( nf, "nameform" );
554
555 prettyPrintIndent( buf );
556 buf.append( "OC " ).append( nf.getStructuralObjectClassOid() );
557 prettyPrintNewLine( buf );
558
559 renderOids( buf, "MUST", nf.getMustAttributeTypeOids() );
560
561 renderOids( buf, "MAY", nf.getMayAttributeTypeOids() );
562
563 renderXSchemaName( nf, buf );
564
565 renderClose( buf );
566
567 return buf.toString();
568 }
569
570
571 private StringBuilder renderStartOidNamesDescObsolete( SchemaObject so, String schemaObjectType )
572 {
573 StringBuilder buf = new StringBuilder();
574
575 if ( style.startWithSchemaType )
576 {
577 buf.append( schemaObjectType ).append( ' ' );
578 }
579
580 buf.append( "( " ).append( so.getOid() );
581
582 renderNames( so, buf );
583
584 renderDescription( so, buf );
585
586 renderObsolete( so, buf );
587 return buf;
588 }
589
590
591 private void renderNames( SchemaObject so, StringBuilder buf )
592 {
593 List<String> names = so.getNames();
594
595 if ( ( names != null ) && !names.isEmpty() )
596 {
597 buf.append( " NAME " );
598 renderQDescrs( buf, names );
599 prettyPrintNewLine( buf );
600 }
601 else
602 {
603 prettyPrintNewLine( buf );
604 }
605 }
606
607
608 private void renderDescription( SchemaObject so, StringBuilder buf )
609 {
610 if ( so.getDescription() != null )
611 {
612 prettyPrintIndent( buf );
613 buf.append( "DESC " );
614 renderQDString( buf, so.getDescription() );
615 prettyPrintNewLine( buf );
616 }
617 }
618
619
620 private void renderObsolete( SchemaObject so, StringBuilder buf )
621 {
622 if ( so.isObsolete() )
623 {
624 prettyPrintIndent( buf );
625 buf.append( "OBSOLETE" );
626 prettyPrintNewLine( buf );
627 }
628 }
629
630
631 private void prettyPrintNewLine( StringBuilder buf )
632 {
633 if ( style.prettyPrint )
634 {
635 buf.append( '\n' );
636 }
637 else
638 {
639 buf.append( " " );
640 }
641 }
642
643
644 private void prettyPrintIndent( StringBuilder buf )
645 {
646 if ( style.prettyPrint )
647 {
648 buf.append( "\t" );
649 }
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665 private StringBuilder renderQDescrs( StringBuilder buf, List<String> qdescrs )
666 {
667 if ( ( qdescrs == null ) || qdescrs.isEmpty() )
668 {
669 return buf;
670 }
671
672 if ( qdescrs.size() == 1 )
673 {
674 buf.append( '\'' ).append( qdescrs.get( 0 ) ).append( '\'' );
675 }
676 else
677 {
678 buf.append( "( " );
679
680 for ( String qdescr : qdescrs )
681 {
682 buf.append( '\'' ).append( qdescr ).append( "' " );
683 }
684
685 buf.append( ")" );
686 }
687
688 return buf;
689 }
690
691
692 private void renderOids( StringBuilder buf, String prefix, List<String> oids )
693 {
694 if ( ( oids != null ) && !oids.isEmpty() )
695 {
696 prettyPrintIndent( buf );
697 buf.append( prefix ).append( ' ' );
698 renderOids( buf, oids );
699 prettyPrintNewLine( buf );
700 }
701 }
702
703
704
705
706
707
708
709
710
711
712
713
714
715 private StringBuilder renderOids( StringBuilder buf, List<String> oids )
716 {
717 if ( oids.size() == 1 )
718 {
719 buf.append( oids.get( 0 ) );
720 }
721 else
722 {
723 buf.append( "( " );
724
725 boolean isFirst = true;
726
727 for ( String oid : oids )
728 {
729 if ( isFirst )
730 {
731 isFirst = false;
732 }
733 else
734 {
735 buf.append( " $ " );
736 }
737
738 buf.append( oid );
739 }
740
741 buf.append( " )" );
742 }
743
744 return buf;
745 }
746
747
748
749
750
751
752
753
754
755 private StringBuilder renderQDString( StringBuilder buf, String qdString )
756 {
757 buf.append( '\'' );
758
759 for ( char c : qdString.toCharArray() )
760 {
761 switch ( c )
762 {
763 case 0x27:
764 buf.append( "\\27" );
765 break;
766
767 case 0x5C:
768 buf.append( "\\5C" );
769 break;
770
771 default:
772 buf.append( c );
773 break;
774 }
775 }
776
777 buf.append( '\'' );
778
779 return buf;
780 }
781
782
783 private StringBuilder renderRuleIds( StringBuilder buf, List<Integer> ruleIds )
784 {
785 if ( ( ruleIds != null ) && !ruleIds.isEmpty() )
786 {
787 prettyPrintIndent( buf );
788 buf.append( "SUP " );
789
790 if ( ruleIds.size() == 1 )
791 {
792 buf.append( ruleIds.get( 0 ) );
793 }
794 else
795 {
796 buf.append( "( " );
797
798 boolean isFirst = true;
799
800 for ( Integer ruleId : ruleIds )
801 {
802 if ( isFirst )
803 {
804 isFirst = false;
805 }
806 else
807 {
808 buf.append( " " );
809 }
810
811 buf.append( ruleId );
812 }
813
814 buf.append( " )" );
815 }
816
817 prettyPrintNewLine( buf );
818 }
819
820 return buf;
821 }
822
823
824 private void renderXSchemaName( SchemaObject oc, StringBuilder buf )
825 {
826 if ( style.printSchemaName )
827 {
828 prettyPrintIndent( buf );
829 buf.append( "X-SCHEMA '" );
830 buf.append( oc.getSchemaName() );
831 buf.append( "'" );
832 prettyPrintNewLine( buf );
833 }
834 }
835
836
837 private void renderClose( StringBuilder buf )
838 {
839 if ( ( style.prettyPrint ) && ( buf.charAt( buf.length() - 1 ) == '\n' ) )
840 {
841 buf.deleteCharAt( buf.length() - 1 );
842 buf.append( " " );
843 }
844
845 buf.append( ")" );
846 }
847 }