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