View Javadoc

1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.ldap.server.partition.impl.btree.jdbm;
18  
19  
20  import java.math.BigInteger;
21  
22  import javax.naming.NamingException;
23  import javax.naming.directory.Attributes;
24  
25  import jdbm.RecordManager;
26  import jdbm.helper.StringComparator;
27  
28  import org.apache.ldap.common.util.BigIntegerComparator;
29  import org.apache.ldap.server.partition.impl.btree.MasterTable;
30  import org.apache.ldap.server.schema.SerializableComparator;
31  
32  
33  /***
34   * The master table used to store the Attributes of entries.
35   *
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   * @version $Rev: 264732 $
38   */
39  public class JdbmMasterTable extends JdbmTable implements MasterTable
40  {
41      private static final StringComparator STRCOMP = new StringComparator();
42      private static final SerializableComparator BIG_INTEGER_COMPARATOR =
43          new SerializableComparator( "1.2.6.1.4.1.18060.1.1.1.2.2" )
44          {
45              private static final long serialVersionUID = 4048791282048841016L;
46  
47              public int compare( Object o1, Object o2 )
48              {
49                  return BigIntegerComparator.INSTANCE.compare( o1, o2 );
50              }
51          };
52      private static final SerializableComparator STRING_COMPARATOR =
53          new SerializableComparator( "1.2.6.1.4.1.18060.1.1.1.2.3" )
54          {
55              private static final long serialVersionUID = 3258689922792961845L;
56  
57              public int compare( Object o1, Object o2 )
58              {
59                  return STRCOMP.compare( o1, o2 );
60              }
61          };
62      /***  */
63      private JdbmTable adminTbl = null;
64  
65  
66      /***
67       * Creates the master entry table using a Berkeley Db for the backing store.
68       *
69       * @param recMan the jdbm record manager
70       * @throws NamingException if there is an error opening the Db file.
71       */
72      public JdbmMasterTable( RecordManager recMan )
73          throws NamingException
74      {
75          super( DBF, recMan, BIG_INTEGER_COMPARATOR );
76          adminTbl = new JdbmTable( "admin", recMan, STRING_COMPARATOR );
77          String seqValue = ( String ) adminTbl.get( SEQPROP_KEY );
78          
79          if ( null == seqValue ) 
80          {
81              adminTbl.put( SEQPROP_KEY, BigInteger.ZERO.toString() );
82          }
83      }
84  
85  
86      /***
87       * Gets the Attributes of an entry from this MasterTable.
88       *
89       * @param id the BigInteger id of the entry to retrieve.
90       * @return the Attributes of the entry with operational attributes and all.
91       * @throws NamingException if there is a read error on the underlying Db.
92       */
93      public Attributes get( BigInteger id ) throws NamingException
94      {
95          return ( Attributes ) super.get( id );
96      }
97  
98  
99      /***
100      * Puts the Attributes of an entry into this master table at an index 
101      * specified by id.  Used both to create new entries and update existing 
102      * ones.
103      *
104      * @param entry the Attributes of entry w/ operational attributes
105      * @param id the BigInteger id of the entry to put
106      * @return the Attributes of the entry put
107      * @throws NamingException if there is a write error on the underlying Db.
108      */
109     public Attributes put( Attributes entry, BigInteger id ) throws NamingException
110     {
111         return ( Attributes ) super.put( id, entry );
112     }
113 
114 
115     /***
116      * Deletes a entry from the master table at an index specified by id.
117      *
118      * @param id the BigInteger id of the entry to delete
119      * @return the Attributes of the deleted entry
120      * @throws NamingException if there is a write error on the underlying Db
121      */
122     public Attributes delete( BigInteger id ) throws NamingException
123     {
124         return ( Attributes ) super.remove( id );
125     }
126 
127 
128     /***
129      * Get's the current id value from this master database's sequence without
130      * affecting the seq.
131      *
132      * @return the current value.
133      * @throws NamingException if the admin table storing sequences cannot be
134      * read.
135      */
136     public BigInteger getCurrentId() throws NamingException
137     {
138         BigInteger id = null;
139 
140         synchronized ( adminTbl ) 
141         {
142             id = new BigInteger( ( String ) adminTbl.get( SEQPROP_KEY ) );
143             
144             if ( null == id ) 
145             {
146                 adminTbl.put( SEQPROP_KEY, BigInteger.ZERO.toString() );
147                 id = BigInteger.ZERO;
148             }
149         }
150 
151         return id;
152     }
153 
154 
155     /***
156      * Get's the next value from this SequenceBDb.  This has the side-effect of
157      * changing the current sequence values perminantly in memory and on disk.
158      * Master table sequence begins at BigInteger.ONE.  The BigInteger.ZERO is
159      * used for the fictitious parent of the suffix root entry.
160      *
161      * @return the current value incremented by one.
162      * @throws NamingException if the admin table storing sequences cannot be
163      * read and writen to.
164      */
165     public BigInteger getNextId() throws NamingException
166     {
167         BigInteger lastVal = null;
168         BigInteger nextVal = null;
169 
170         synchronized ( adminTbl ) 
171         {
172             lastVal = new BigInteger( ( String ) 
173                 adminTbl.get( SEQPROP_KEY ) );
174             
175             if ( null == lastVal ) 
176             {
177                 adminTbl.put( SEQPROP_KEY, BigInteger.ONE.toString() );
178                 return BigInteger.ONE;
179             } 
180             else 
181             {
182                 nextVal = lastVal.add( BigInteger.ONE );
183                 adminTbl.put( SEQPROP_KEY, nextVal.toString() );
184             }
185         }
186 
187         return nextVal;
188     }
189 
190 
191     /***
192      * Gets a persistant property stored in the admin table of this MasterTable.
193      *
194      * @param property the key of the property to get the value of
195      * @return the value of the property
196      * @throws NamingException when the underlying admin table cannot be read
197      */
198     public String getProperty( String property ) throws NamingException
199     {
200         synchronized ( adminTbl ) 
201         {
202             return ( String ) adminTbl.get( property );
203         }
204     }
205 
206 
207     /***
208      * Sets a persistant property stored in the admin table of this MasterTable.
209      *
210      * @param property the key of the property to set the value of
211      * @param value the value of the property
212      * @throws NamingException when the underlying admin table cannot be writen
213      */
214     public void setProperty( String property, String value ) throws NamingException
215     {
216         synchronized ( adminTbl ) 
217         {
218             adminTbl.put( property, value );
219         }
220     }
221 }