KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.sql.Connection JavaDoc;
24 import java.sql.PreparedStatement JavaDoc;
25 import java.sql.ResultSet JavaDoc;
26 import java.sql.SQLException JavaDoc;
27
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30
31 /**
32  * The SequenceIdGenerator requests each Id using a sequence in a database. While not
33  * actually pooling batches of Ids like other IdGenerator implementations, making use of this class
34  * does make code compatable with other IdGenerators on a configuration basis.
35  * <p>
36  * The Configuration to use a SequenceIdGenerator look like the following:
37  * <pre>
38  * &lt;id-generators&gt;
39  * &lt;sequence name="user-ids" logger="cm.ids"&gt;
40  * &lt;dbpool&gt;user-db&lt;/dbpool&gt;
41  * &lt;query&gt;SELECT NEXTVAL('category_ids')&lt;/query&gt;
42  * &lt;/sequence&gt;
43  * &lt;/id-generators&gt;
44  * </pre>
45  * or
46  * <pre>
47  * &lt;id-generators&gt;
48  * &lt;sequence name="user-ids" logger="cm.ids"&gt;
49  * &lt;dbpool&gt;user-db&lt;/dbpool&gt;
50  * &lt;query&gt;SELECT category_ids.nextval FROM DUAL&lt;/query&gt;
51  * &lt;/sequence&gt;
52  * &lt;/id-generators&gt;
53  * </pre>
54  * Where user-db is the name of a DataSource configured in a datasources element, and query is
55  * any query which will return a single id while maintaining state so that successive calls
56  * will continue to return incremented ids.
57  * <p>
58  *
59  * With the following roles declaration:
60  * <pre>
61  * &lt;role name="org.apache.avalon.excalibur.datasource.ids.IdGeneratorSelector"
62  * shorthand="id-generators"
63  * default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
64  * &lt;hint shorthand="sequence"
65  * class="org.apache.avalon.excalibur.datasource.ids.SequenceIdGenerator"/&gt;
66  * &lt;/role&gt;
67  * </pre>
68  *
69  * To configure your component to use the IdGenerator declared above, its configuration should look
70  * something like the following:
71  * <pre>
72  * &lt;user-service logger="cm"&gt;
73  * &lt;dbpool&gt;user-db&lt;/dbpool&gt;
74  * &lt;id-generator&gt;user-ids&lt;/id-generator&gt;
75  * &lt;/user-service&gt;
76  * </pre>
77  *
78  * Your component obtains a reference to an IdGenerator using the same method as it obtains a
79  * DataSource, by making use of a ComponentSelector.
80  *
81  * @avalon.component
82  * @avalon.service type=org.apache.avalon.excalibur.datasource.ids.IdGenerator
83  * @x-avalon.info name=sequence-id-generator
84  * @x-avalon.lifestyle type=singleton
85  *
86  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
87  * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:17 $
88  * @since 4.1
89  */

90 public class SequenceIdGenerator
91     extends AbstractDataSourceIdGenerator
92 {
93     private String JavaDoc m_query;
94
95     /*---------------------------------------------------------------
96      * Constructors
97      *-------------------------------------------------------------*/

98     public SequenceIdGenerator()
99     {
100     }
101
102     /*---------------------------------------------------------------
103      * AbstractIdGenerator Methods
104      *-------------------------------------------------------------*/

105     /**
106      * Gets the next id as a Big Decimal. This method will only be called
107      * when synchronized and when the data type is configured to be BigDecimal.
108      *
109      * @return the next id as a BigDecimal.
110      *
111      * @throws IdException if an Id could not be allocated for any reason.
112      */

113     protected BigDecimal JavaDoc getNextBigDecimalIdInner()
114         throws IdException
115     {
116         if( getLogger().isDebugEnabled() )
117         {
118             getLogger().debug( "Requesting an Id using query: " + m_query );
119         }
120
121         try
122         {
123             Connection JavaDoc conn = getConnection();
124             try
125             {
126                 PreparedStatement JavaDoc stmt = conn.prepareStatement( m_query );
127                 ResultSet JavaDoc rs = stmt.executeQuery();
128                 if( rs.next() )
129                 {
130                     return rs.getBigDecimal( 1 );
131                 }
132                 else
133                 {
134                     String JavaDoc msg = "Query for Id did not return a value";
135                     getLogger().error( msg );
136                     throw new IdException( msg );
137                 }
138             }
139             finally
140             {
141                 conn.close();
142             }
143         }
144         catch( SQLException JavaDoc e )
145         {
146             String JavaDoc msg = "Unable to allocate an Id";
147             getLogger().error( msg );
148             throw new IdException( msg, e );
149         }
150     }
151
152     /**
153      * Gets the next id as a long. This method will only be called
154      * when synchronized and when the data type is configured to be long.
155      *
156      * @return the next id as a long.
157      *
158      * @throws IdException if an Id could not be allocated for any reason.
159      */

160     protected long getNextLongIdInner()
161         throws IdException
162     {
163         if( getLogger().isDebugEnabled() )
164         {
165             getLogger().debug( "Requesting an Id using query: " + m_query );
166         }
167
168         try
169         {
170             Connection JavaDoc conn = getConnection();
171             try
172             {
173                 PreparedStatement JavaDoc stmt = conn.prepareStatement( m_query );
174                 ResultSet JavaDoc rs = stmt.executeQuery();
175                 if( rs.next() )
176                 {
177                     return rs.getLong( 1 );
178                 }
179                 else
180                 {
181                     String JavaDoc msg = "Query for Id did not return a value";
182                     getLogger().error( msg );
183                     throw new IdException( msg );
184                 }
185             }
186             finally
187             {
188                 conn.close();
189             }
190         }
191         catch( SQLException JavaDoc e )
192         {
193             String JavaDoc msg = "Unable to allocate an Id";
194             getLogger().error( msg );
195             throw new IdException( msg, e );
196         }
197     }
198
199     /*---------------------------------------------------------------
200      * Configurable Methods
201      *-------------------------------------------------------------*/

202     /**
203      * Called by the Container to configure the component.
204      *
205      * @param configuration configuration info used to setup the component.
206      *
207      * @throws ConfigurationException if there are any problems with the configuration.
208      */

209     public void configure( Configuration configuration )
210         throws ConfigurationException
211     {
212         super.configure( configuration );
213
214         // Obtain the query to use to obtain an id from a sequence.
215
m_query = configuration.getChild( "query" ).getValue();
216     }
217 }
218
219
Popular Tags