KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > util > sequence > SequenceManagerNextValImpl


1 package org.apache.ojb.broker.util.sequence;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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 implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.sql.ResultSet JavaDoc;
19 import java.sql.Statement JavaDoc;
20 import java.sql.PreparedStatement JavaDoc;
21
22 import org.apache.commons.lang.SystemUtils;
23 import org.apache.ojb.broker.PersistenceBroker;
24 import org.apache.ojb.broker.accesslayer.StatementManagerIF;
25 import org.apache.ojb.broker.metadata.ClassDescriptor;
26 import org.apache.ojb.broker.metadata.FieldDescriptor;
27 import org.apache.ojb.broker.query.Query;
28 import org.apache.ojb.broker.util.logging.Logger;
29 import org.apache.ojb.broker.util.logging.LoggerFactory;
30
31 /**
32  * This SequenceManager implementation uses database
33  * sequence key generation (e.g supported by
34  * Oracle, SAP DB, PostgreSQL, ...).
35  * This class is responsible for creating new unique ID's.
36  * <br/>
37  * It is possible to define a <code>sequence-name</code>
38  * field-descriptor attribute in the repository file. If
39  * such an attribute was not found, the implementation build
40  * an extent aware sequence name by its own.
41  * <br/>
42  * Keep in mind when define a sequence name, that you are responsible
43  * to be aware of extents, that is: if you ask for an uid for an
44  * interface with several
45  * implementor classes, or a baseclass with several subclasses the returned
46  * uid have to be unique accross all tables representing objects of the
47  * extent in question. Thus you have to use the same <code>sequence-name</code>
48  * for all extents.
49  *
50  * <p>
51  * Implementation configuration properties:
52  * </p>
53  *
54  * <table cellspacing="2" cellpadding="2" border="3" frame="box">
55  * <tr>
56  * <td><strong>Property Key</strong></td>
57  * <td><strong>Property Values</strong></td>
58  * </tr>
59  * <tr>
60  * <td>autoNaming</td>
61  * <td>
62  * Default was 'true'. If set 'true' OJB try to build a
63  * sequence name automatic if none found in field-descriptor
64  * and set this generated name as <code>sequence-name</code>
65  * in field-descriptor.
66  * <br/>
67  * If set 'false' OJB throws an exception
68  * if none sequence name was found in field-descriptor, ditto
69  * OJB does NOT try to create a database sequence entry when
70  * for given sequence name no database sequence could be found.
71  * </td>
72  * </tr>
73  * </table>
74  *
75  *
76  * <br/>
77  * <p>
78  * <b>Limitations:</b>
79  * <ul>
80  * <li>none</li>
81  * </ul>
82  * </p>
83  * <br/>
84  * <br/>
85  *
86  * @author Edson Carlos Ericksson Richter
87  * @author Rajeev Kaul
88  * @author Thomas Mahler
89  * @author Armin Waibel
90  * @version $Id: SequenceManagerNextValImpl.java,v 1.17.2.4 2005/12/21 22:28:41 tomdz Exp $
91  */

92 public class SequenceManagerNextValImpl extends AbstractSequenceManager
93 {
94     private Logger log = LoggerFactory.getLogger(SequenceManagerNextValImpl.class);
95
96     /**
97      *
98      */

99     public SequenceManagerNextValImpl(PersistenceBroker broker)
100     {
101         super(broker);
102     }
103
104     /**
105      * returns a unique int value for class clazz and field fieldName.
106      * the returned number is unique accross all tables in the extent of clazz.
107      */

108     protected int getUniqueId(FieldDescriptor field) throws SequenceManagerException
109     {
110         return (int) getUniqueLong(field);
111     }
112
113
114     /**
115      * returns a unique long value for class clazz and field fieldName.
116      * the returned number is unique accross all tables in the extent of clazz.
117      */

118     protected long getUniqueLong(FieldDescriptor field) throws SequenceManagerException
119     {
120         long result;
121         // lookup sequence name
122
String JavaDoc sequenceName = calculateSequenceName(field);
123         try
124         {
125             result = buildNextSequence(field.getClassDescriptor(), sequenceName);
126         }
127         catch (Throwable JavaDoc e)
128         {
129             // maybe the sequence was not created
130
try
131             {
132                 log.info("Create DB sequence key '"+sequenceName+"'");
133                 createSequence(field.getClassDescriptor(), sequenceName);
134             }
135             catch (Exception JavaDoc e1)
136             {
137                 throw new SequenceManagerException(
138                         SystemUtils.LINE_SEPARATOR +
139                         "Could not grab next id, failed with " + SystemUtils.LINE_SEPARATOR +
140                         e.getMessage() + SystemUtils.LINE_SEPARATOR +
141                         "Creation of new sequence failed with " +
142                         SystemUtils.LINE_SEPARATOR + e1.getMessage() + SystemUtils.LINE_SEPARATOR
143                         , e1);
144             }
145             try
146             {
147                 result = buildNextSequence(field.getClassDescriptor(), sequenceName);
148             }
149             catch (Throwable JavaDoc e1)
150             {
151                 throw new SequenceManagerException("Could not grab next id, sequence seems to exist", e);
152             }
153         }
154         return result;
155     }
156
157     protected long buildNextSequence(ClassDescriptor cld, String JavaDoc sequenceName) throws Exception JavaDoc
158     {
159         ResultSet JavaDoc rs = null;
160         PreparedStatement JavaDoc stmt = null;
161         long result = -1;
162         StatementManagerIF stmtMan = getBrokerForClass().serviceStatementManager();
163         try
164         {
165             stmt = stmtMan.getPreparedStatement(cld, getPlatform().nextSequenceQuery(sequenceName) ,Query.NOT_SCROLLABLE, 1, false);
166             rs = stmt.executeQuery();
167             rs.next();
168             result = rs.getLong(1);
169         }
170         finally
171         {
172             stmtMan.closeResources(stmt, rs);
173         }
174         return result;
175     }
176
177     protected void createSequence(ClassDescriptor cld, String JavaDoc sequenceName) throws Exception JavaDoc
178     {
179         Statement JavaDoc stmt = null;
180         StatementManagerIF stmtMan = getBrokerForClass().serviceStatementManager();
181 // arminw: never try to remove existing sequences, because this may lead in unexpected behaviour
182
// if the reason for the create call isn't a missing sequence (e.g. network problems)
183
// try
184
// {
185
// stmt = stmtMan.getGenericStatement(cld, Query.NOT_SCROLLABLE);
186
// stmt.execute(getPlatform().dropSequenceQuery(sequenceName));
187
// }
188
// catch (Exception ignore)
189
// {
190
// // ignore it
191
// }
192
// finally
193
// {
194
// try
195
// {
196
// stmtMan.closeResources(stmt, null);
197
// }
198
// catch (Exception ignore)
199
// {
200
// // ignore it
201
// }
202
// }
203

204         try
205         {
206             stmt = stmtMan.getGenericStatement(cld, Query.NOT_SCROLLABLE);
207             stmt.execute(getPlatform().createSequenceQuery(sequenceName, getConfigurationProperties()));
208         }
209         finally
210         {
211             try
212             {
213                 stmtMan.closeResources(stmt, null);
214             }
215             catch (Exception JavaDoc e)
216             {
217                 e.printStackTrace();
218             }
219         }
220     }
221 }
222
Popular Tags