KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > datasource > ids > AbstractIdGenerator


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 package org.apache.avalon.excalibur.datasource.ids;
21
22 import java.math.BigDecimal JavaDoc;
23
24 import org.apache.avalon.framework.logger.AbstractLogEnabled;
25 import org.apache.avalon.framework.thread.ThreadSafe;
26
27 /**
28  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
29  * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
30  * @since 4.1
31  */

32 public abstract class AbstractIdGenerator
33     extends AbstractLogEnabled
34     implements IdGenerator, ThreadSafe
35 {
36     private static final BigDecimal JavaDoc BIG_DECIMAL_MAX_LONG = new BigDecimal JavaDoc( Long.MAX_VALUE );
37
38     /**
39      * Used to manage internal synchronization.
40      */

41     private Object JavaDoc m_semaphore = new Object JavaDoc();
42
43     /**
44      * Data type for the Id Pool.
45      */

46     private boolean m_useBigDecimals;
47
48     /*---------------------------------------------------------------
49      * Constructors
50      *-------------------------------------------------------------*/

51     public AbstractIdGenerator()
52     {
53     }
54
55     /*---------------------------------------------------------------
56      * Methods
57      *-------------------------------------------------------------*/

58     /**
59      * Gets the next id as a Big Decimal. This method will only be called
60      * when synchronized and when the data type is configured to be BigDecimal.
61      *
62      * @return the next id as a BigDecimal.
63      *
64      * @throws IdException if an Id could not be allocated for any reason.
65      */

66     protected abstract BigDecimal JavaDoc getNextBigDecimalIdInner()
67         throws IdException;
68
69     /**
70      * Gets the next id as a long. This method will only be called
71      * when synchronized and when the data type is configured to be long.
72      *
73      * @return the next id as a long.
74      *
75      * @throws IdException if an Id could not be allocated for any reason.
76      */

77     protected abstract long getNextLongIdInner()
78         throws IdException;
79
80     /**
81      * By default, the IdGenerator will operate using a backend datatype of type long. This
82      * is the most efficient, however it does not allow for Ids that are larger than
83      * Long.MAX_VALUE. To allow very large Ids, it is necessary to make use of the BigDecimal
84      * data storage type. This method should only be called durring initialization.
85      *
86      * @param useBigDecimals True to set BigDecimal as the internal data type.
87      */

88     protected final void setUseBigDecimals( boolean useBigDecimals )
89     {
90         m_useBigDecimals = useBigDecimals;
91     }
92
93     /**
94      * Returns true if the internal data type is using BigDecimals, false if it is using longs.
95      */

96     protected final boolean isUsingBigDecimals()
97     {
98         return m_useBigDecimals;
99     }
100
101     /**
102      * Gets the next Long Id constraining the value to be less than the specified maxId.
103      *
104      * @throws IdException if the next id is larger than the specified maxId.
105      */

106     protected final long getNextLongIdChecked( long maxId )
107         throws IdException
108     {
109         long nextId;
110         if( m_useBigDecimals )
111         {
112             // Use BigDecimal data type
113
BigDecimal JavaDoc bd;
114             synchronized( m_semaphore )
115             {
116                 bd = getNextBigDecimalIdInner();
117             }
118
119             // Make sure that the Big Decimal value can be assigned to a long before continuing.
120
if( bd.compareTo( BIG_DECIMAL_MAX_LONG ) > 0 )
121             {
122                 String JavaDoc msg = "Unable to provide an id. The next id would " +
123                     "be greater than the id data type allows.";
124                 getLogger().error( msg );
125                 throw new IdException( msg );
126             }
127             nextId = bd.longValue();
128         }
129         else
130         {
131             // Use long data type
132
synchronized( m_semaphore )
133             {
134                 nextId = getNextLongIdInner();
135             }
136         }
137
138         // Make sure that the id is valid for the requested data type.
139
if( nextId > maxId )
140         {
141             String JavaDoc msg = "Unable to provide an id. The next id would " +
142                 "be greater than the id data type allows.";
143             getLogger().error( msg );
144             throw new IdException( msg );
145         }
146
147         return nextId;
148     }
149
150     /*---------------------------------------------------------------
151      * IdGenerator Methods
152      *-------------------------------------------------------------*/

153     /**
154      * Returns the next Id from the pool.
155      *
156      * @return the next Id.
157      */

158     public final BigDecimal JavaDoc getNextBigDecimalId()
159         throws IdException
160     {
161         BigDecimal JavaDoc bd;
162         if( m_useBigDecimals )
163         {
164             // Use BigDecimal data type
165
synchronized( m_semaphore )
166             {
167                 bd = getNextBigDecimalIdInner();
168             }
169         }
170         else
171         {
172             // Use long data type
173
synchronized( m_semaphore )
174             {
175                 bd = new BigDecimal JavaDoc( getNextLongIdInner() );
176             }
177         }
178
179         return bd;
180     }
181
182     /**
183      * Returns the next Id from the pool.
184      *
185      * @return the next Id.
186      *
187      * @throws IdException if the next id is outside of the range of valid longs.
188      */

189     public final long getNextLongId()
190         throws IdException
191     {
192         return getNextLongIdChecked( Long.MAX_VALUE );
193     }
194
195     /**
196      * Returns the next Id from the pool.
197      *
198      * @return the next Id.
199      *
200      * @throws IdException if the next id is outside of the range of valid integers.
201      */

202     public final int getNextIntegerId()
203         throws IdException
204     {
205         return (int)getNextLongIdChecked( Integer.MAX_VALUE );
206     }
207
208     /**
209      * Returns the next Id from the pool.
210      *
211      * @return the next Id.
212      *
213      * @throws IdException if the next id is outside of the range of valid shorts.
214      */

215     public final short getNextShortId()
216         throws IdException
217     {
218         return (short)getNextLongIdChecked( Short.MAX_VALUE );
219     }
220
221     /**
222      * Returns the next Id from the pool.
223      *
224      * @return the next Id.
225      *
226      * @throws IdException if the next id is outside of the range of valid bytes.
227      */

228     public final byte getNextByteId()
229         throws IdException
230     {
231         return (byte)getNextLongIdChecked( Byte.MAX_VALUE );
232     }
233 }
234
235
Popular Tags