View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.server.core.partition.impl.btree.mavibot;
21  
22  
23  import java.io.DataInputStream;
24  import java.io.DataOutputStream;
25  import java.io.IOException;
26  import java.io.RandomAccessFile;
27  import java.nio.charset.StandardCharsets;
28  
29  import org.apache.directory.api.ldap.model.entry.DefaultEntry;
30  import org.apache.directory.api.ldap.model.entry.Entry;
31  import org.apache.directory.api.ldap.model.ldif.LdifEntry;
32  import org.apache.directory.api.ldap.model.ldif.LdifReader;
33  import org.apache.directory.api.ldap.model.name.Dn;
34  import org.apache.directory.api.ldap.model.schema.SchemaManager;
35  import org.apache.directory.mavibot.btree.Tuple;
36  import org.apache.directory.mavibot.btree.util.TupleReaderWriter;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  
41  /**
42   * TODO LdifTupleReaderWriter.
43   *
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   */
46  public class LdifTupleReaderWriter<E> implements TupleReaderWriter<Dn, E>
47  {
48  
49      private LdifReader reader = null;
50  
51      private static final Logger LOG = LoggerFactory.getLogger( LdifTupleReaderWriter.class );
52  
53      private String ldifFile;
54      
55      private RandomAccessFile raf;
56      
57      private SchemaManager schemaManager;
58      
59      public LdifTupleReaderWriter( String ldifFile, SchemaManager schemaManager )
60      {
61          this.ldifFile = ldifFile;
62          this.schemaManager = schemaManager;
63          
64          try
65          {
66              raf = new RandomAccessFile( ldifFile, "r" );
67          }
68          catch ( Exception e )
69          {
70              throw new RuntimeException( e );
71          }
72      }
73      
74  
75      @Override
76      public Tuple<Dn, E> readSortedTuple( DataInputStream in )
77      {
78          try
79          {
80              if ( in.available() > 0 )
81              {
82                  Tuple<Dn, E> tuple = new Tuple<>();
83                  tuple.setKey( new Dn( in.readUTF() ) );
84                  
85                  String[] tokens = in.readUTF().split( ":" );
86                  
87                  long offset = Long.parseLong( tokens[0] );
88                  
89                  int length = Integer.parseInt( tokens[1] );
90                  
91                  raf.seek( offset );
92                  
93                  byte[] data = new byte[length];
94                  
95                  raf.read( data, 0, length );
96                  
97                  try ( LdifReader ldifReader = new LdifReader() )
98                  {
99                      LdifEntry ldifEntry = ldifReader.parseLdif( new String( data, StandardCharsets.UTF_8 ) ).get( 0 );
100                     Entry entry = new DefaultEntry( schemaManager, ldifEntry.getEntry() );
101     
102                     tuple.setValue( ( E ) entry );
103                 }
104                 
105                 return tuple;
106             }
107         }
108         catch ( Exception e )
109         {
110             LOG.error( "Failed to read a sorted tuple", e );
111         }
112         
113         return null;
114     }
115 
116 
117     @Override
118     public Tuple<Dn, E> readUnsortedTuple( DataInputStream in )
119     {
120         try
121         {
122             if ( reader == null )
123             {
124                 reader = new LdifReader( in );
125             }
126         }
127         catch ( Exception e )
128         {
129             String msg = "Failed to open the LDIF input stream";
130             LOG.error( msg, e );
131 
132             throw new RuntimeException( msg, e );
133         }
134 
135         Tuple<Dn, E> t = null;
136 
137         if ( reader.hasNext() )
138         {
139             LdifEntry ldifEntry = reader.next();
140 
141             if ( ldifEntry == null )
142             {
143                 throw new IllegalStateException(
144                     "Received null entry while parsing, check the LDIF file for possible incorrect/corrupted entries" );
145             }
146 
147             t = new Tuple<>();
148 
149             t.setKey( ldifEntry.getDn() );
150             t.setValue( ( E ) ( ldifEntry.getOffset() + ":" + ldifEntry.getLengthBeforeParsing() ) );
151         }
152 
153         return t;
154     }
155 
156 
157     @Override
158     public void storeSortedTuple( Tuple<Dn, E> t, DataOutputStream out ) throws IOException
159     {
160         out.writeUTF( t.getKey().getName() );
161         out.writeUTF( ( String ) t.getValue() );
162     }
163 
164 }