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.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 }