1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }