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.ldif;
21
22
23 import java.io.BufferedReader;
24 import java.io.Closeable;
25 import java.io.DataInputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileReader;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.Reader;
34 import java.io.StringReader;
35 import java.io.UnsupportedEncodingException;
36 import java.net.MalformedURLException;
37 import java.net.URL;
38 import java.nio.charset.Charset;
39 import java.util.ArrayList;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.NoSuchElementException;
43
44 import org.apache.directory.api.asn1.util.Oid;
45 import org.apache.directory.api.i18n.I18n;
46 import org.apache.directory.api.ldap.model.entry.Attribute;
47 import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
48 import org.apache.directory.api.ldap.model.entry.ModificationOperation;
49 import org.apache.directory.api.ldap.model.exception.LdapException;
50 import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
51 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
52 import org.apache.directory.api.ldap.model.message.Control;
53 import org.apache.directory.api.ldap.model.name.Dn;
54 import org.apache.directory.api.ldap.model.schema.AttributeType;
55 import org.apache.directory.api.ldap.model.schema.SchemaManager;
56 import org.apache.directory.api.util.Base64;
57 import org.apache.directory.api.util.Chars;
58 import org.apache.directory.api.util.Strings;
59 import org.apache.directory.api.util.exception.NotImplementedException;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public class LdifReader implements Iterable<LdifEntry>, Closeable
171 {
172
173 private static final Logger LOG = LoggerFactory.getLogger( LdifReader.class );
174
175
176 protected List<String> lines;
177
178
179 protected int position;
180
181
182 protected static final int DEFAULT_VERSION = 1;
183
184
185 protected int version;
186
187
188 protected static final int LDIF_ENTRY = 0;
189
190
191 protected static final int CHANGE = 1;
192
193
194 protected static final int UNKNOWN = 2;
195
196
197 protected long sizeLimit = SIZE_LIMIT_DEFAULT;
198
199
200 protected static final long SIZE_LIMIT_DEFAULT = 1024000;
201
202
203 protected static final int MOD_SPEC = 0;
204
205
206 protected static final int ATTRVAL_SPEC = 1;
207
208
209 protected static final int ATTRVAL_SPEC_OR_SEP = 2;
210
211
212 protected LdifEntry prefetched;
213
214
215 protected Reader reader;
216
217
218 protected boolean containsEntries;
219
220
221 protected boolean containsChanges;
222
223
224 protected SchemaManager schemaManager;
225
226
227
228
229
230 protected Exception error;
231
232
233 protected int entryLen = 0;
234
235
236 protected long entryOffset = 0;
237
238
239 protected long offset = 0;
240
241
242 protected int lineNumber;
243
244
245 protected boolean validateDn = true;
246
247
248
249
250
251 public LdifReader()
252 {
253 lines = new ArrayList<String>();
254 position = 0;
255 version = DEFAULT_VERSION;
256 }
257
258
259
260
261
262 public LdifReader( SchemaManager schemaManager )
263 {
264 lines = new ArrayList<String>();
265 position = 0;
266 version = DEFAULT_VERSION;
267 this.schemaManager = schemaManager;
268 }
269
270
271
272
273
274 private void initReader( BufferedReader reader ) throws LdapException
275 {
276 this.reader = reader;
277 init();
278 }
279
280
281
282
283
284
285
286 public void init() throws LdapException
287 {
288 lines = new ArrayList<String>();
289 position = 0;
290 version = DEFAULT_VERSION;
291 containsChanges = false;
292 containsEntries = false;
293
294
295 version = parseVersion();
296 prefetched = parseEntry();
297 }
298
299
300
301
302
303
304
305
306 public LdifReader( String ldifFileName ) throws LdapLdifException
307 {
308 File file = new File( ldifFileName );
309
310 if ( !file.exists() )
311 {
312 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
313 LOG.error( msg );
314 throw new LdapLdifException( msg );
315 }
316
317 if ( !file.canRead() )
318 {
319 String msg = I18n.err( I18n.ERR_12011_CANNOT_READ_FILE, file.getName() );
320 LOG.error( msg );
321 throw new LdapLdifException( msg );
322 }
323
324 try
325 {
326 initReader( new BufferedReader( new FileReader( file ) ) );
327 }
328 catch ( FileNotFoundException fnfe )
329 {
330 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
331 LOG.error( msg );
332 throw new LdapLdifException( msg, fnfe );
333 }
334 catch ( LdapInvalidDnException lide )
335 {
336 throw new LdapLdifException( lide.getMessage(), lide );
337 }
338 catch ( LdapException le )
339 {
340 throw new LdapLdifException( le.getMessage(), le );
341 }
342 }
343
344
345
346
347
348
349
350
351 public LdifReader( Reader in ) throws LdapException
352 {
353 initReader( new BufferedReader( in ) );
354 }
355
356
357
358
359
360
361
362
363 public LdifReader( InputStream in ) throws LdapException
364 {
365 initReader( new BufferedReader( new InputStreamReader( in ) ) );
366 }
367
368
369
370
371
372
373
374
375 public LdifReader( File file ) throws LdapLdifException
376 {
377 if ( !file.exists() )
378 {
379 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
380 LOG.error( msg );
381 throw new LdapLdifException( msg );
382 }
383
384 if ( !file.canRead() )
385 {
386 String msg = I18n.err( I18n.ERR_12011_CANNOT_READ_FILE, file.getName() );
387 LOG.error( msg );
388 throw new LdapLdifException( msg );
389 }
390
391 try
392 {
393 initReader( new BufferedReader( new FileReader( file ) ) );
394 }
395 catch ( FileNotFoundException fnfe )
396 {
397 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
398 LOG.error( msg );
399 throw new LdapLdifException( msg, fnfe );
400 }
401 catch ( LdapInvalidDnException lide )
402 {
403 throw new LdapLdifException( lide.getMessage(), lide );
404 }
405 catch ( LdapException le )
406 {
407 throw new LdapLdifException( le.getMessage(), le );
408 }
409 }
410
411
412
413
414
415
416
417
418
419 public LdifReader( File file, SchemaManager schemaManager ) throws LdapLdifException
420 {
421 if ( !file.exists() )
422 {
423 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
424 LOG.error( msg );
425 throw new LdapLdifException( msg );
426 }
427
428 if ( !file.canRead() )
429 {
430 String msg = I18n.err( I18n.ERR_12011_CANNOT_READ_FILE, file.getName() );
431 LOG.error( msg );
432 throw new LdapLdifException( msg );
433 }
434
435 this.schemaManager = schemaManager;
436
437 try
438 {
439 initReader( new BufferedReader( new FileReader( file ) ) );
440 }
441 catch ( FileNotFoundException fnfe )
442 {
443 String msg = I18n.err( I18n.ERR_12010_CANNOT_FIND_FILE, file.getAbsoluteFile() );
444 LOG.error( msg );
445 throw new LdapLdifException( msg, fnfe );
446 }
447 catch ( LdapInvalidDnException lide )
448 {
449 throw new LdapLdifException( lide.getMessage(), lide );
450 }
451 catch ( LdapException le )
452 {
453 throw new LdapLdifException( le.getMessage(), le );
454 }
455 }
456
457
458
459
460
461 public int getVersion()
462 {
463 return version;
464 }
465
466
467
468
469
470 public long getSizeLimit()
471 {
472 return sizeLimit;
473 }
474
475
476
477
478
479
480
481 public void setSizeLimit( long sizeLimit )
482 {
483 this.sizeLimit = sizeLimit;
484 }
485
486
487
488 private void parseFill( char[] document )
489 {
490 while ( Chars.isCharASCII( document, position, ' ' ) )
491 {
492 position++;
493 }
494 }
495
496
497
498
499
500
501
502
503
504
505
506
507
508 private String parseNumber( char[] document )
509 {
510 int initPos = position;
511
512 while ( true )
513 {
514 if ( Chars.isDigit( document, position ) )
515 {
516 position++;
517 }
518 else
519 {
520 break;
521 }
522 }
523
524 if ( position == initPos )
525 {
526 return null;
527 }
528 else
529 {
530 return new String( document, initPos, position - initPos );
531 }
532 }
533
534
535
536
537
538
539
540
541 protected ChangeType parseChangeType( String line )
542 {
543 ChangeType operation = ChangeType.Add;
544
545 String modOp = Strings.trim( line.substring( "changetype:".length() + 1 ) );
546
547 if ( "add".equalsIgnoreCase( modOp ) )
548 {
549 operation = ChangeType.Add;
550 }
551 else if ( "delete".equalsIgnoreCase( modOp ) )
552 {
553 operation = ChangeType.Delete;
554 }
555 else if ( "modify".equalsIgnoreCase( modOp ) )
556 {
557 operation = ChangeType.Modify;
558 }
559 else if ( "moddn".equalsIgnoreCase( modOp ) )
560 {
561 operation = ChangeType.ModDn;
562 }
563 else if ( "modrdn".equalsIgnoreCase( modOp ) )
564 {
565 operation = ChangeType.ModRdn;
566 }
567
568 return operation;
569 }
570
571
572
573
574
575
576
577
578
579 protected String parseDn( String line ) throws LdapLdifException
580 {
581 String dn;
582
583 String lowerLine = Strings.toLowerCase( line );
584
585 if ( lowerLine.startsWith( "dn:" ) || lowerLine.startsWith( "Dn:" ) )
586 {
587
588 int length = line.length();
589
590 if ( length == 3 )
591 {
592
593 dn = "";
594 }
595 else if ( line.charAt( 3 ) == ':' )
596 {
597 if ( length > 4 )
598 {
599
600 String trimmedLine = line.substring( 4 ).trim();
601
602 try
603 {
604 dn = new String( Base64.decode( trimmedLine.toCharArray() ), "UTF-8" );
605 }
606 catch ( UnsupportedEncodingException uee )
607 {
608
609 LOG.error( I18n.err( I18n.ERR_12014_BASE64_DN_EXPECTED, lineNumber ) );
610 throw new LdapLdifException( I18n.err( I18n.ERR_12015_INVALID_BASE64_DN ), uee );
611 }
612 }
613 else
614 {
615
616 LOG.error( I18n.err( I18n.ERR_12012_EMPTY_DN_NOT_ALLOWED, lineNumber ) );
617 throw new LdapLdifException( I18n.err( I18n.ERR_12013_NO_DN ) );
618 }
619 }
620 else
621 {
622 dn = line.substring( 3 ).trim();
623 }
624 }
625 else
626 {
627 LOG.error( I18n.err( I18n.ERR_12016_DN_EXPECTED, lineNumber ) );
628 throw new LdapLdifException( I18n.err( I18n.ERR_12013_NO_DN ) );
629 }
630
631
632 if ( validateDn && !Dn.isValid( dn ) )
633 {
634 String message = I18n.err( I18n.ERR_12017_INVALID_DN, dn, lineNumber );
635 LOG.error( message );
636 throw new LdapLdifException( message );
637 }
638
639 return dn;
640 }
641
642
643
644
645
646
647
648
649
650 protected static Object parseSimpleValue( String line, int pos )
651 {
652 if ( line.length() > pos + 1 )
653 {
654 char c = line.charAt( pos + 1 );
655
656 if ( c == ':' )
657 {
658 String value = Strings.trim( line.substring( pos + 2 ) );
659
660 return Base64.decode( value.toCharArray() );
661 }
662 else
663 {
664 return Strings.trim( line.substring( pos + 1 ) );
665 }
666 }
667 else
668 {
669 return null;
670 }
671 }
672
673
674
675
676
677
678
679
680
681
682 protected Object parseValue( String line, int pos ) throws LdapLdifException
683 {
684 if ( line.length() > pos + 1 )
685 {
686 char c = line.charAt( pos + 1 );
687
688 if ( c == ':' )
689 {
690 String value = Strings.trim( line.substring( pos + 2 ) );
691
692 return Base64.decode( value.toCharArray() );
693 }
694 else if ( c == '<' )
695 {
696 String urlName = Strings.trim( line.substring( pos + 2 ) );
697
698 try
699 {
700 URL url = new URL( urlName );
701
702 if ( "file".equals( url.getProtocol() ) )
703 {
704 String fileName = url.getFile();
705
706 File file = new File( fileName );
707
708 if ( !file.exists() )
709 {
710 LOG.error( I18n.err( I18n.ERR_12018_FILE_NOT_FOUND, fileName, lineNumber ) );
711 throw new LdapLdifException( I18n.err( I18n.ERR_12019_BAD_URL_FILE_NOT_FOUND ) );
712 }
713 else
714 {
715 long length = file.length();
716
717 if ( length > sizeLimit )
718 {
719 String message = I18n.err( I18n.ERR_12020_FILE_TOO_BIG, fileName, lineNumber );
720 LOG.error( message );
721 throw new LdapLdifException( message );
722 }
723 else
724 {
725 byte[] data = new byte[( int ) length];
726 DataInputStream inf = null;
727
728 try
729 {
730 inf = new DataInputStream( new FileInputStream( file ) );
731 inf.readFully( data );
732
733 return data;
734 }
735 catch ( FileNotFoundException fnfe )
736 {
737
738
739
740 LOG.error( I18n.err( I18n.ERR_12018_FILE_NOT_FOUND, fileName, lineNumber ) );
741 throw new LdapLdifException( I18n.err( I18n.ERR_12019_BAD_URL_FILE_NOT_FOUND ),
742 fnfe );
743 }
744 catch ( IOException ioe )
745 {
746 LOG.error( I18n.err( I18n.ERR_12022_ERROR_READING_FILE, fileName, lineNumber ) );
747 throw new LdapLdifException( I18n.err( I18n.ERR_12023_ERROR_READING_BAD_URL ), ioe );
748 }
749 finally
750 {
751 try
752 {
753 if ( inf != null )
754 {
755 inf.close();
756 }
757 }
758 catch ( IOException ioe )
759 {
760 LOG.error(
761 I18n.err( I18n.ERR_12024_CANNOT_CLOSE_FILE, ioe.getMessage(), lineNumber ),
762 ioe );
763
764 }
765 }
766 }
767 }
768 }
769 else
770 {
771 LOG.error( I18n.err( I18n.ERR_12025_BAD_PROTOCOL ) );
772 throw new LdapLdifException( I18n.err( I18n.ERR_12026_UNSUPPORTED_PROTOCOL, lineNumber ) );
773 }
774 }
775 catch ( MalformedURLException mue )
776 {
777 String message = I18n.err( I18n.ERR_12027_BAD_URL, urlName, lineNumber );
778 LOG.error( message );
779 throw new LdapLdifException( message, mue );
780 }
781 }
782 else
783 {
784 String value = Strings.trimLeft( line.substring( pos + 1 ) );
785 int end = value.length();
786
787 for ( int i = value.length() - 1; i > 0; i-- )
788 {
789 char cc = value.charAt( i );
790
791 if ( cc == ' ' )
792 {
793 if ( value.charAt( i - 1 ) == '\\' )
794 {
795
796 break;
797 }
798 else
799 {
800 end = i;
801 }
802 }
803 else
804 {
805 break;
806 }
807 }
808
809 String result = null;
810
811 result = value.substring( 0, end );
812
813 return result;
814 }
815 }
816 else
817 {
818 return null;
819 }
820 }
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845 private Control parseControl( String line ) throws LdapLdifException
846 {
847 String lowerLine = Strings.toLowerCase( line ).trim();
848 char[] controlValue = line.trim().toCharArray();
849 int pos = 0;
850 int length = controlValue.length;
851
852
853 if ( pos > length )
854 {
855
856 LOG.error( I18n.err( I18n.ERR_12029_CONTROL_WITHOUT_OID, lineNumber ) );
857 throw new LdapLdifException( I18n.err( I18n.ERR_12029_CONTROL_WITHOUT_OID ) );
858 }
859
860 int initPos = pos;
861
862 while ( Chars.isCharASCII( controlValue, pos, '.' ) || Chars.isDigit( controlValue, pos ) )
863 {
864 pos++;
865 }
866
867 if ( pos == initPos )
868 {
869
870 LOG.error( I18n.err( I18n.ERR_12029_CONTROL_WITHOUT_OID, lineNumber ) );
871 throw new LdapLdifException( I18n.err( I18n.ERR_12029_CONTROL_WITHOUT_OID ) );
872 }
873
874
875 String oidString = lowerLine.substring( 0, pos );
876
877 if ( !Oid.isOid( oidString ) )
878 {
879 String message = I18n.err( I18n.ERR_12031_INVALID_OID, oidString, lineNumber );
880 LOG.error( message );
881 throw new LdapLdifException( message );
882 }
883
884 LdifControl control = new LdifControl( oidString );
885
886
887
888 while ( Chars.isCharASCII( controlValue, pos, ' ' ) )
889 {
890 pos++;
891 }
892
893
894 int criticalPos = lowerLine.indexOf( ':' );
895
896 int criticalLength;
897
898 if ( criticalPos == -1 )
899 {
900 criticalLength = length - pos;
901 }
902 else
903 {
904 criticalLength = criticalPos - pos;
905 }
906
907 if ( ( criticalLength == 4 ) && ( "true".equalsIgnoreCase( lowerLine.substring( pos, pos + 4 ) ) ) )
908 {
909 control.setCritical( true );
910 }
911 else if ( ( criticalLength == 5 ) && ( "false".equalsIgnoreCase( lowerLine.substring( pos, pos + 5 ) ) ) )
912 {
913 control.setCritical( false );
914 }
915 else if ( criticalLength != 0 )
916 {
917
918
919 LOG.error( I18n.err( I18n.ERR_12033_INVALID_CRITICALITY, lineNumber ) );
920 throw new LdapLdifException( I18n.err( I18n.ERR_12033_INVALID_CRITICALITY ) );
921 }
922
923 if ( criticalPos > 0 )
924 {
925
926
927 if ( Chars.isCharASCII( controlValue, criticalPos + 1, ':' ) )
928 {
929
930
931
932 pos = criticalPos + 2;
933
934 while ( Chars.isCharASCII( controlValue, pos, ' ' ) )
935 {
936 pos++;
937 }
938
939 byte[] value = Base64.decode( line.substring( pos ).toCharArray() );
940 control.setValue( value );
941 }
942 else if ( Chars.isCharASCII( controlValue, criticalPos + 1, '<' ) )
943 {
944
945 throw new NotImplementedException( "See DIRSERVER-1547" );
946 }
947 else
948 {
949
950 pos = criticalPos + 1;
951
952 while ( Chars.isCharASCII( controlValue, pos, ' ' ) )
953 {
954 pos++;
955 }
956
957
958 byte[] value = new byte[length - pos];
959
960 for ( int i = 0; i < length - pos; i++ )
961 {
962 value[i] = ( byte ) controlValue[i + pos];
963 }
964
965 control.setValue( value );
966 }
967 }
968
969 return control;
970 }
971
972
973
974
975
976
977
978
979 public static Attribute parseAttributeValue( String line )
980 {
981 int colonIndex = line.indexOf( ':' );
982
983 if ( colonIndex != -1 )
984 {
985 String attributeType = line.substring( 0, colonIndex );
986 Object attributeValue = parseSimpleValue( line, colonIndex );
987
988
989 if ( attributeValue instanceof String )
990 {
991 return new DefaultAttribute( attributeType, ( String ) attributeValue );
992 }
993 else
994 {
995 return new DefaultAttribute( attributeType, ( byte[] ) attributeValue );
996 }
997 }
998 else
999 {
1000 return null;
1001 }
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013 public void parseAttributeValue( LdifEntry entry, String line, String lowerLine ) throws LdapException
1014 {
1015 int colonIndex = line.indexOf( ':' );
1016
1017 String attributeType = lowerLine.substring( 0, colonIndex );
1018
1019
1020 if ( attributeType.equals( "dn" ) )
1021 {
1022 LOG.error( I18n.err( I18n.ERR_12002_ENTRY_WITH_TWO_DNS, lineNumber ) );
1023 throw new LdapLdifException( I18n.err( I18n.ERR_12003_LDIF_ENTRY_WITH_TWO_DNS ) );
1024 }
1025
1026 Object attributeValue = parseValue( line, colonIndex );
1027
1028 if ( schemaManager != null )
1029 {
1030 AttributeType at = schemaManager.getAttributeType( attributeType );
1031
1032 if ( at != null )
1033 {
1034 if ( at.getSyntax().isHumanReadable() )
1035 {
1036 if ( attributeValue instanceof byte[] )
1037 {
1038 attributeValue = Strings.utf8ToString( ( byte[] ) attributeValue );
1039 }
1040 }
1041 else
1042 {
1043 if ( attributeValue instanceof String )
1044 {
1045 attributeValue = Strings.getBytesUtf8( ( String ) attributeValue );
1046 }
1047 }
1048 }
1049 }
1050
1051
1052 entry.addAttribute( attributeType, attributeValue );
1053 }
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 private void parseModRdn( LdifEntry entry, Iterator<String> iter ) throws LdapLdifException
1064 {
1065
1066
1067 if ( iter.hasNext() )
1068 {
1069 String line = iter.next();
1070 String lowerLine = Strings.toLowerCase( line );
1071
1072 if ( lowerLine.startsWith( "newrdn::" ) || lowerLine.startsWith( "newrdn:" ) )
1073 {
1074 int colonIndex = line.indexOf( ':' );
1075 Object attributeValue = parseValue( line, colonIndex );
1076
1077 if ( attributeValue instanceof String )
1078 {
1079 entry.setNewRdn( ( String ) attributeValue );
1080 }
1081 else
1082 {
1083 entry.setNewRdn( Strings.utf8ToString( ( byte[] ) attributeValue ) );
1084 }
1085 }
1086 else
1087 {
1088 LOG.error( I18n.err( I18n.ERR_12035_BAD_MODRDN_OPERATION, lineNumber ) );
1089 throw new LdapLdifException( I18n.err( I18n.ERR_12035_BAD_MODRDN_OPERATION ) );
1090 }
1091 }
1092 else
1093 {
1094 LOG.error( I18n.err( I18n.ERR_12035_BAD_MODRDN_OPERATION, lineNumber ) );
1095 throw new LdapLdifException( I18n.err( I18n.ERR_12035_BAD_MODRDN_OPERATION ) );
1096 }
1097
1098 if ( iter.hasNext() )
1099 {
1100 String line = iter.next();
1101 String lowerLine = Strings.toLowerCase( line );
1102
1103 if ( lowerLine.startsWith( "deleteoldrdn:" ) )
1104 {
1105 int colonIndex = line.indexOf( ':' );
1106 Object attributeValue = parseValue( line, colonIndex );
1107 entry.setDeleteOldRdn( "1".equals( attributeValue ) );
1108 }
1109 else
1110 {
1111 LOG.error( I18n.err( I18n.ERR_12038_NO_DELETEOLDRDN, lineNumber ) );
1112 throw new LdapLdifException( I18n.err( I18n.ERR_12038_NO_DELETEOLDRDN ) );
1113 }
1114 }
1115 else
1116 {
1117 LOG.error( I18n.err( I18n.ERR_12038_NO_DELETEOLDRDN, lineNumber ) );
1118 throw new LdapLdifException( I18n.err( I18n.ERR_12038_NO_DELETEOLDRDN ) );
1119 }
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 private void parseModify( LdifEntry entry, Iterator<String> iter ) throws LdapLdifException
1142 {
1143 int state = MOD_SPEC;
1144 String modified = null;
1145 ModificationOperation modificationType = ModificationOperation.ADD_ATTRIBUTE;
1146 Attribute attribute = null;
1147
1148
1149 boolean isEmptyValue = true;
1150
1151 while ( iter.hasNext() )
1152 {
1153 String line = iter.next();
1154 String lowerLine = Strings.toLowerCase( line );
1155
1156 if ( lowerLine.startsWith( "-" ) )
1157 {
1158 if ( ( state != ATTRVAL_SPEC_OR_SEP ) && ( state != ATTRVAL_SPEC ) )
1159 {
1160 LOG.error( I18n.err( I18n.ERR_12040_BAD_MODIFY_SEPARATOR, lineNumber ) );
1161 throw new LdapLdifException( I18n.err( I18n.ERR_12040_BAD_MODIFY_SEPARATOR ) );
1162 }
1163 else
1164 {
1165 if ( isEmptyValue )
1166 {
1167
1168 entry.addModification( modificationType, modified, null );
1169 }
1170 else
1171 {
1172
1173 entry.addModification( modificationType, attribute );
1174 }
1175
1176 state = MOD_SPEC;
1177 isEmptyValue = true;
1178 }
1179 }
1180 else if ( lowerLine.startsWith( "add:" ) )
1181 {
1182 if ( ( state != MOD_SPEC ) && ( state != ATTRVAL_SPEC ) )
1183 {
1184 LOG.error( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2, lineNumber ) );
1185 throw new LdapLdifException( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2 ) );
1186 }
1187
1188 modified = Strings.trim( line.substring( "add:".length() ) );
1189 modificationType = ModificationOperation.ADD_ATTRIBUTE;
1190 attribute = new DefaultAttribute( modified );
1191
1192 state = ATTRVAL_SPEC;
1193 }
1194 else if ( lowerLine.startsWith( "delete:" ) )
1195 {
1196 if ( ( state != MOD_SPEC ) && ( state != ATTRVAL_SPEC ) )
1197 {
1198 LOG.error( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2, lineNumber ) );
1199 throw new LdapLdifException( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2 ) );
1200 }
1201
1202 modified = Strings.trim( line.substring( "delete:".length() ) );
1203 modificationType = ModificationOperation.REMOVE_ATTRIBUTE;
1204 attribute = new DefaultAttribute( modified );
1205 isEmptyValue = false;
1206
1207 state = ATTRVAL_SPEC_OR_SEP;
1208 }
1209 else if ( lowerLine.startsWith( "replace:" ) )
1210 {
1211 if ( ( state != MOD_SPEC ) && ( state != ATTRVAL_SPEC ) )
1212 {
1213 LOG.error( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2, lineNumber ) );
1214 throw new LdapLdifException( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2 ) );
1215 }
1216
1217 modified = Strings.trim( line.substring( "replace:".length() ) );
1218 modificationType = ModificationOperation.REPLACE_ATTRIBUTE;
1219 attribute = new DefaultAttribute( modified );
1220
1221 state = ATTRVAL_SPEC_OR_SEP;
1222 }
1223 else
1224 {
1225 if ( ( state != ATTRVAL_SPEC ) && ( state != ATTRVAL_SPEC_OR_SEP ) )
1226 {
1227 LOG.error( I18n.err( I18n.ERR_12040_BAD_MODIFY_SEPARATOR, lineNumber ) );
1228 throw new LdapLdifException( I18n.err( I18n.ERR_12040_BAD_MODIFY_SEPARATOR ) );
1229 }
1230
1231
1232 int colonIndex = line.indexOf( ':' );
1233
1234 String attributeType = line.substring( 0, colonIndex );
1235
1236 if ( !attributeType.equalsIgnoreCase( modified ) )
1237 {
1238 LOG.error( I18n.err( I18n.ERR_12044, lineNumber ) );
1239 throw new LdapLdifException( I18n.err( I18n.ERR_12045 ) );
1240 }
1241
1242
1243 if ( attributeType.equalsIgnoreCase( "dn" ) )
1244 {
1245 LOG.error( I18n.err( I18n.ERR_12002_ENTRY_WITH_TWO_DNS, lineNumber ) );
1246 throw new LdapLdifException( I18n.err( I18n.ERR_12003_LDIF_ENTRY_WITH_TWO_DNS ) );
1247 }
1248
1249 Object attributeValue = parseValue( line, colonIndex );
1250
1251 try
1252 {
1253 if ( attributeValue instanceof String )
1254 {
1255 attribute.add( ( String ) attributeValue );
1256 }
1257 else
1258 {
1259 attribute.add( ( byte[] ) attributeValue );
1260 }
1261 }
1262 catch ( LdapInvalidAttributeValueException liave )
1263 {
1264 throw new LdapLdifException( liave.getMessage(), liave );
1265 }
1266
1267 isEmptyValue = false;
1268
1269 state = ATTRVAL_SPEC_OR_SEP;
1270 }
1271 }
1272
1273 if ( state != MOD_SPEC )
1274 {
1275 LOG.error( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2, lineNumber ) );
1276 throw new LdapLdifException( I18n.err( I18n.ERR_12042_BAD_MODIFY_SEPARATOR_2 ) );
1277 }
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 private void parseChange( LdifEntry entry, Iterator<String> iter, ChangeType operation ) throws LdapException
1315 {
1316
1317 entry.setChangeType( operation );
1318
1319 switch ( operation )
1320 {
1321 case Delete:
1322
1323
1324 return;
1325
1326 case Add:
1327
1328 while ( iter.hasNext() )
1329 {
1330 String line = iter.next();
1331 String lowerLine = Strings.toLowerCase( line );
1332 parseAttributeValue( entry, line, lowerLine );
1333 }
1334
1335 return;
1336
1337 case Modify:
1338 parseModify( entry, iter );
1339 return;
1340
1341 case ModDn:
1342 case ModRdn:
1343
1344 parseModRdn( entry, iter );
1345
1346
1347 if ( iter.hasNext() )
1348 {
1349 String line = iter.next();
1350 String lowerLine = Strings.toLowerCase( line );
1351
1352 if ( lowerLine.startsWith( "newsuperior:" ) )
1353 {
1354 int colonIndex = line.indexOf( ':' );
1355 Object attributeValue = parseValue( line, colonIndex );
1356
1357 if ( attributeValue instanceof String )
1358 {
1359 entry.setNewSuperior( ( String ) attributeValue );
1360 }
1361 else
1362 {
1363 entry.setNewSuperior( Strings.utf8ToString( ( byte[] ) attributeValue ) );
1364 }
1365 }
1366 else
1367 {
1368 if ( operation == ChangeType.ModDn )
1369 {
1370 LOG.error( I18n.err( I18n.ERR_12046, lineNumber ) );
1371 throw new LdapLdifException( I18n.err( I18n.ERR_12047 ) );
1372 }
1373 }
1374 }
1375
1376 return;
1377
1378 default:
1379
1380 LOG.error( I18n.err( I18n.ERR_12048, lineNumber ) );
1381 throw new LdapLdifException( I18n.err( I18n.ERR_12049 ) );
1382 }
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400 protected LdifEntry parseEntry() throws LdapException
1401 {
1402 if ( ( lines == null ) || ( lines.size() == 0 ) )
1403 {
1404 LOG.debug( "The entry is empty : end of ldif file" );
1405 return null;
1406 }
1407
1408
1409 String line = lines.get( 0 );
1410
1411 lineNumber -= ( lines.size() - 1 );
1412
1413 String name = parseDn( line );
1414
1415 Dn dn = new Dn( schemaManager, name );
1416
1417
1418 LdifEntry entry = createLdifEntry( schemaManager );
1419 entry.setLengthBeforeParsing( entryLen );
1420 entry.setOffset( entryOffset );
1421
1422 entry.setDn( dn );
1423
1424
1425 lines.remove( 0 );
1426
1427
1428 Iterator<String> iter = lines.iterator();
1429
1430
1431 int type = LDIF_ENTRY;
1432
1433
1434
1435 boolean controlSeen = false;
1436
1437
1438
1439 boolean changeTypeSeen = false;
1440
1441 ChangeType operation = ChangeType.Add;
1442 String lowerLine;
1443 Control control;
1444
1445 while ( iter.hasNext() )
1446 {
1447 lineNumber++;
1448
1449
1450
1451 line = iter.next();
1452 lowerLine = Strings.toLowerCase( line );
1453
1454
1455
1456
1457
1458 if ( lowerLine.startsWith( "control:" ) )
1459 {
1460 if ( containsEntries )
1461 {
1462 LOG.error( I18n.err( I18n.ERR_12004_CHANGE_NOT_ALLOWED, lineNumber ) );
1463 throw new LdapLdifException( I18n.err( I18n.ERR_12005_NO_CHANGE ) );
1464 }
1465
1466 containsChanges = true;
1467
1468 if ( controlSeen )
1469 {
1470 LOG.error( I18n.err( I18n.ERR_12050, lineNumber ) );
1471 throw new LdapLdifException( I18n.err( I18n.ERR_12051 ) );
1472 }
1473
1474
1475 control = parseControl( line.substring( "control:".length() ) );
1476 entry.addControl( control );
1477 }
1478 else if ( lowerLine.startsWith( "changetype:" ) )
1479 {
1480 if ( containsEntries )
1481 {
1482 LOG.error( I18n.err( I18n.ERR_12004_CHANGE_NOT_ALLOWED, lineNumber ) );
1483 throw new LdapLdifException( I18n.err( I18n.ERR_12005_NO_CHANGE ) );
1484 }
1485
1486 containsChanges = true;
1487
1488 if ( changeTypeSeen )
1489 {
1490 LOG.error( I18n.err( I18n.ERR_12052, lineNumber ) );
1491 throw new LdapLdifException( I18n.err( I18n.ERR_12053 ) );
1492 }
1493
1494
1495 type = CHANGE;
1496 controlSeen = true;
1497
1498 operation = parseChangeType( line );
1499
1500
1501 parseChange( entry, iter, operation );
1502 changeTypeSeen = true;
1503 }
1504 else if ( line.indexOf( ':' ) > 0 )
1505 {
1506 if ( containsChanges )
1507 {
1508 LOG.error( I18n.err( I18n.ERR_12004_CHANGE_NOT_ALLOWED, lineNumber ) );
1509 throw new LdapLdifException( I18n.err( I18n.ERR_12005_NO_CHANGE ) );
1510 }
1511
1512 containsEntries = true;
1513
1514 if ( controlSeen || changeTypeSeen )
1515 {
1516 LOG.error( I18n.err( I18n.ERR_12054, lineNumber ) );
1517 throw new LdapLdifException( I18n.err( I18n.ERR_12055 ) );
1518 }
1519
1520 parseAttributeValue( entry, line, lowerLine );
1521 type = LDIF_ENTRY;
1522 }
1523 else
1524 {
1525
1526 LOG.error( I18n.err( I18n.ERR_12056, lineNumber ) );
1527 throw new LdapLdifException( I18n.err( I18n.ERR_12057_BAD_ATTRIBUTE ) );
1528 }
1529 }
1530
1531 if ( type == LDIF_ENTRY )
1532 {
1533 LOG.debug( "Read an entry : {}", entry );
1534 }
1535 else if ( type == CHANGE )
1536 {
1537 entry.setChangeType( operation );
1538 LOG.debug( "Read a modification : {}", entry );
1539 }
1540 else
1541 {
1542 LOG.error( I18n.err( I18n.ERR_12058_UNKNOWN_ENTRY_TYPE, lineNumber ) );
1543 throw new LdapLdifException( I18n.err( I18n.ERR_12059_UNKNOWN_ENTRY ) );
1544 }
1545
1546 return entry;
1547 }
1548
1549
1550
1551
1552
1553
1554
1555
1556 protected int parseVersion() throws LdapLdifException
1557 {
1558 int ver = DEFAULT_VERSION;
1559
1560
1561 readLines();
1562
1563 if ( lines.size() == 0 )
1564 {
1565 LOG.warn( "The ldif file is empty" );
1566 return ver;
1567 }
1568
1569
1570 String line = lines.get( 0 );
1571
1572
1573 char[] document = line.toCharArray();
1574 String versionNumber;
1575
1576 if ( line.startsWith( "version:" ) )
1577 {
1578 position += "version:".length();
1579 parseFill( document );
1580
1581
1582 versionNumber = parseNumber( document );
1583
1584
1585 if ( position != document.length )
1586 {
1587 LOG.error( I18n.err( I18n.ERR_12060_VERSION_NOT_A_NUMBER, lineNumber ) );
1588 throw new LdapLdifException( I18n.err( I18n.ERR_12061_LDIF_PARSING_ERROR ) );
1589 }
1590
1591 try
1592 {
1593 ver = Integer.parseInt( versionNumber );
1594 }
1595 catch ( NumberFormatException nfe )
1596 {
1597 LOG.error( I18n.err( I18n.ERR_12060_VERSION_NOT_A_NUMBER, lineNumber ) );
1598 throw new LdapLdifException( I18n.err( I18n.ERR_12061_LDIF_PARSING_ERROR ), nfe );
1599 }
1600
1601 LOG.debug( "Ldif version : {}", versionNumber );
1602
1603
1604 lines.remove( 0 );
1605
1606
1607 if ( lines.size() == 0 )
1608 {
1609
1610 int tmpEntryLen = entryLen;
1611
1612 readLines();
1613
1614 entryLen += tmpEntryLen;
1615 }
1616 }
1617 else
1618 {
1619 LOG.info( "No version information : assuming version: 1" );
1620 }
1621
1622 return ver;
1623 }
1624
1625
1626
1627
1628
1629
1630
1631
1632 protected String getLine() throws IOException
1633 {
1634 return ( ( BufferedReader ) reader ).readLine();
1635 }
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646 protected void readLines() throws LdapLdifException
1647 {
1648 String line;
1649 boolean insideComment = true;
1650 boolean isFirstLine = true;
1651
1652 lines.clear();
1653 entryLen = 0;
1654 entryOffset = offset;
1655
1656 StringBuffer sb = new StringBuffer();
1657
1658 try
1659 {
1660 while ( ( line = getLine() ) != null )
1661 {
1662 lineNumber++;
1663
1664 if ( line.length() == 0 )
1665 {
1666 if ( isFirstLine )
1667 {
1668 continue;
1669 }
1670 else
1671 {
1672
1673 insideComment = false;
1674 offset++;
1675 break;
1676 }
1677 }
1678
1679
1680 switch ( line.charAt( 0 ) )
1681 {
1682 case '#':
1683 insideComment = true;
1684 break;
1685
1686 case ' ':
1687 isFirstLine = false;
1688
1689 if ( insideComment )
1690 {
1691 continue;
1692 }
1693 else if ( sb.length() == 0 )
1694 {
1695 LOG.error( I18n.err( I18n.ERR_12062_EMPTY_CONTINUATION_LINE, lineNumber ) );
1696 throw new LdapLdifException( I18n.err( I18n.ERR_12061_LDIF_PARSING_ERROR ) );
1697 }
1698 else
1699 {
1700 sb.append( line.substring( 1 ) );
1701 }
1702
1703 insideComment = false;
1704 break;
1705
1706 default:
1707 isFirstLine = false;
1708
1709
1710
1711 if ( sb.length() != 0 )
1712 {
1713 lines.add( sb.toString() );
1714 }
1715
1716 sb = new StringBuffer( line );
1717 insideComment = false;
1718 break;
1719 }
1720
1721 byte[] data = line.getBytes();
1722
1723 offset += ( data.length + 1 );
1724 entryLen += ( data.length + 1 );
1725 }
1726 }
1727 catch ( IOException ioe )
1728 {
1729 throw new LdapLdifException( I18n.err( I18n.ERR_12063_ERROR_WHILE_READING_LDIF_LINE ), ioe );
1730 }
1731
1732
1733 if ( sb.length() != 0 )
1734 {
1735 lines.add( sb.toString() );
1736 }
1737 }
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 public List<LdifEntry> parseLdifFile( String fileName ) throws LdapLdifException
1748 {
1749 return parseLdifFile( fileName, Charset.forName( Strings.getDefaultCharsetName() ).toString() );
1750 }
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761 public List<LdifEntry> parseLdifFile( String fileName, String encoding ) throws LdapLdifException
1762 {
1763 if ( Strings.isEmpty( fileName ) )
1764 {
1765 LOG.error( I18n.err( I18n.ERR_12064_EMPTY_FILE_NAME ) );
1766 throw new LdapLdifException( I18n.err( I18n.ERR_12064_EMPTY_FILE_NAME ) );
1767 }
1768
1769 File file = new File( fileName );
1770
1771 if ( !file.exists() )
1772 {
1773 LOG.error( I18n.err( I18n.ERR_12066, fileName ) );
1774 throw new LdapLdifException( I18n.err( I18n.ERR_12067, fileName ) );
1775 }
1776
1777 BufferedReader reader = null;
1778
1779
1780 try
1781 {
1782 reader = new BufferedReader(
1783 new InputStreamReader( new FileInputStream( file ), Charset.forName( encoding ) ) );
1784
1785 return parseLdif( reader );
1786 }
1787 catch ( FileNotFoundException fnfe )
1788 {
1789 LOG.error( I18n.err( I18n.ERR_12068, fileName ) );
1790 throw new LdapLdifException( I18n.err( I18n.ERR_12067, fileName ), fnfe );
1791 }
1792 catch ( LdapException le )
1793 {
1794 throw new LdapLdifException( le.getMessage(), le );
1795 }
1796 finally
1797 {
1798
1799 try
1800 {
1801 if ( reader != null )
1802 {
1803 reader.close();
1804 }
1805 }
1806 catch ( IOException ioe )
1807 {
1808
1809 }
1810 }
1811 }
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821 public List<LdifEntry> parseLdif( String ldif ) throws LdapLdifException
1822 {
1823 LOG.debug( "Starts parsing ldif buffer" );
1824
1825 if ( Strings.isEmpty( ldif ) )
1826 {
1827 return new ArrayList<LdifEntry>();
1828 }
1829
1830 BufferedReader reader = new BufferedReader( new StringReader( ldif ) );
1831
1832 try
1833 {
1834 List<LdifEntry> entries = parseLdif( reader );
1835
1836 if ( LOG.isDebugEnabled() )
1837 {
1838 LOG.debug( "Parsed {} entries.", ( entries == null ? Integer.valueOf( 0 ) : Integer.valueOf( entries
1839 .size() ) ) );
1840 }
1841
1842 return entries;
1843 }
1844 catch ( LdapLdifException ne )
1845 {
1846 LOG.error( I18n.err( I18n.ERR_12069, ne.getLocalizedMessage() ) );
1847 throw new LdapLdifException( I18n.err( I18n.ERR_12070 ), ne );
1848 }
1849 catch ( LdapException le )
1850 {
1851 throw new LdapLdifException( le.getMessage(), le );
1852 }
1853 finally
1854 {
1855
1856 try
1857 {
1858 reader.close();
1859 }
1860 catch ( IOException ioe )
1861 {
1862 throw new LdapLdifException( I18n.err( I18n.ERR_12024_CANNOT_CLOSE_FILE ), ioe );
1863 }
1864
1865 }
1866 }
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877 private LdifEntry nextInternal()
1878 {
1879 try
1880 {
1881 LOG.debug( "next(): -- called" );
1882
1883 LdifEntry entry = prefetched;
1884 readLines();
1885
1886 try
1887 {
1888 prefetched = parseEntry();
1889 }
1890 catch ( LdapLdifException ne )
1891 {
1892 error = ne;
1893 throw new NoSuchElementException( ne.getMessage() );
1894 }
1895 catch ( LdapException le )
1896 {
1897 throw new NoSuchElementException( le.getMessage() );
1898 }
1899
1900 LOG.debug( "next(): -- returning ldif {}\n", entry );
1901
1902 return entry;
1903 }
1904 catch ( LdapLdifException ne )
1905 {
1906 LOG.error( I18n.err( I18n.ERR_12071 ) );
1907 error = ne;
1908 return null;
1909 }
1910 }
1911
1912
1913
1914
1915
1916
1917
1918 public LdifEntry next()
1919 {
1920 return nextInternal();
1921 }
1922
1923
1924
1925
1926
1927
1928
1929 public LdifEntry fetch()
1930 {
1931 return prefetched;
1932 }
1933
1934
1935
1936
1937
1938
1939
1940 private boolean hasNextInternal()
1941 {
1942 return null != prefetched;
1943 }
1944
1945
1946
1947
1948
1949
1950
1951 public boolean hasNext()
1952 {
1953 if ( prefetched != null )
1954 {
1955 LOG.debug( "hasNext(): -- returning true" );
1956 }
1957 else
1958 {
1959 LOG.debug( "hasNext(): -- returning false" );
1960 }
1961
1962 return hasNextInternal();
1963 }
1964
1965
1966
1967
1968
1969
1970
1971 private void removeInternal()
1972 {
1973 throw new UnsupportedOperationException();
1974 }
1975
1976
1977
1978
1979
1980
1981
1982 public void remove()
1983 {
1984 removeInternal();
1985 }
1986
1987
1988
1989
1990
1991 public Iterator<LdifEntry> iterator()
1992 {
1993 return new Iterator<LdifEntry>()
1994 {
1995 public boolean hasNext()
1996 {
1997 return hasNextInternal();
1998 }
1999
2000
2001 public LdifEntry next()
2002 {
2003 return nextInternal();
2004 }
2005
2006
2007 public void remove()
2008 {
2009 throw new UnsupportedOperationException();
2010 }
2011 };
2012 }
2013
2014
2015
2016
2017
2018 public boolean hasError()
2019 {
2020 return error != null;
2021 }
2022
2023
2024
2025
2026
2027 public Exception getError()
2028 {
2029 return error;
2030 }
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041 public List<LdifEntry> parseLdif( BufferedReader reader ) throws LdapException
2042 {
2043
2044 List<LdifEntry> entries = new ArrayList<LdifEntry>();
2045
2046 this.reader = reader;
2047
2048
2049 version = parseVersion();
2050 prefetched = parseEntry();
2051
2052
2053 try
2054 {
2055 for ( LdifEntry entry : this )
2056 {
2057 if ( entry != null )
2058 {
2059 entries.add( entry );
2060 }
2061 }
2062 }
2063 catch ( NoSuchElementException nsee )
2064 {
2065 throw new LdapLdifException( I18n.err( I18n.ERR_12072, error.getLocalizedMessage() ), nsee );
2066 }
2067
2068 return entries;
2069 }
2070
2071
2072
2073
2074
2075 public boolean containsEntries()
2076 {
2077 return containsEntries;
2078 }
2079
2080
2081
2082
2083
2084 public int getLineNumber()
2085 {
2086 return lineNumber;
2087 }
2088
2089
2090
2091
2092
2093
2094 protected LdifEntry createLdifEntry( SchemaManager schemaManager )
2095 {
2096 if ( schemaManager != null )
2097 {
2098 return new LdifEntry( schemaManager );
2099 }
2100 else
2101 {
2102 return new LdifEntry();
2103 }
2104 }
2105
2106
2107
2108
2109
2110 public boolean isValidateDn()
2111 {
2112 return validateDn;
2113 }
2114
2115
2116
2117
2118
2119
2120
2121 public void setValidateDn( boolean validateDn )
2122 {
2123 this.validateDn = validateDn;
2124 }
2125
2126
2127
2128
2129
2130 public void setSchemaManager( SchemaManager schemaManager )
2131 {
2132 this.schemaManager = schemaManager;
2133 }
2134
2135
2136
2137
2138
2139 public void close() throws IOException
2140 {
2141 if ( reader != null )
2142 {
2143 position = 0;
2144 reader.close();
2145 containsEntries = false;
2146 containsChanges = false;
2147 offset = entryOffset = lineNumber = 0;
2148 }
2149 }
2150 }