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 private StringBuilder renderQDescrs( StringBuilder buf, List<String> qdescrs )
664 {
665 if ( ( qdescrs == null ) || qdescrs.isEmpty() )
666 {
667 return buf;
668 }
669
670 if ( qdescrs.size() == 1 )
671 {
672 buf.append( '\'' ).append( qdescrs.get( 0 ) ).append( '\'' );
673 }
674 else
675 {
676 buf.append( "( " );
677
678 for ( String qdescr : qdescrs )
679 {
680 buf.append( '\'' ).append( qdescr ).append( "' " );
681 }
682
683 buf.append( ")" );
684 }
685
686 return buf;
687 }
688
689
690 private void renderOids( StringBuilder buf, String prefix, List<String> oids )
691 {
692 if ( ( oids != null ) && !oids.isEmpty() )
693 {
694 prettyPrintIndent( buf );
695 buf.append( prefix ).append( ' ' );
696 renderOids( buf, oids );
697 prettyPrintNewLine( buf );
698 }
699 }
700
701
702
703
704
705
706
707
708
709
710
711
712 private StringBuilder renderOids( StringBuilder buf, List<String> oids )
713 {
714 if ( oids.size() == 1 )
715 {
716 buf.append( oids.get( 0 ) );
717 }
718 else
719 {
720 buf.append( "( " );
721
722 boolean isFirst = true;
723
724 for ( String oid : oids )
725 {
726 if ( isFirst )
727 {
728 isFirst = false;
729 }
730 else
731 {
732 buf.append( " $ " );
733 }
734
735 buf.append( oid );
736 }
737
738 buf.append( " )" );
739 }
740
741 return buf;
742 }
743
744
745
746
747
748
749
750
751 private StringBuilder renderQDString( StringBuilder buf, String qdString )
752 {
753 buf.append( '\'' );
754
755 for ( char c : qdString.toCharArray() )
756 {
757 switch ( c )
758 {
759 case 0x27:
760 buf.append( "\\27" );
761 break;
762
763 case 0x5C:
764 buf.append( "\\5C" );
765 break;
766
767 default:
768 buf.append( c );
769 break;
770 }
771 }
772
773 buf.append( '\'' );
774
775 return buf;
776 }
777
778
779 private StringBuilder renderRuleIds( StringBuilder buf, List<Integer> ruleIds )
780 {
781 if ( ( ruleIds != null ) && !ruleIds.isEmpty() )
782 {
783 prettyPrintIndent( buf );
784 buf.append( "SUP " );
785
786 if ( ruleIds.size() == 1 )
787 {
788 buf.append( ruleIds.get( 0 ) );
789 }
790 else
791 {
792 buf.append( "( " );
793
794 boolean isFirst = true;
795
796 for ( Integer ruleId : ruleIds )
797 {
798 if ( isFirst )
799 {
800 isFirst = false;
801 }
802 else
803 {
804 buf.append( " " );
805 }
806
807 buf.append( ruleId );
808 }
809
810 buf.append( " )" );
811 }
812
813 prettyPrintNewLine( buf );
814 }
815
816 return buf;
817 }
818
819
820 private void renderXSchemaName( SchemaObject oc, StringBuilder buf )
821 {
822 if ( style.printSchemaName )
823 {
824 prettyPrintIndent( buf );
825 buf.append( "X-SCHEMA '" );
826 buf.append( oc.getSchemaName() );
827 buf.append( "'" );
828 prettyPrintNewLine( buf );
829 }
830 }
831
832
833 private void renderClose( StringBuilder buf )
834 {
835 if ( ( style.prettyPrint ) && ( buf.charAt( buf.length() - 1 ) == '\n' ) )
836 {
837 buf.deleteCharAt( buf.length() - 1 );
838 buf.append( " " );
839 }
840
841 buf.append( ")" );
842 }
843
844 }