View Javadoc

1   /* Version 1.0 based on Apache Software License 1.1
2    *
3    * Copyright (c) 2003 Piotr Maj and DBMonster developers. All rights
4    * reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions are
8    * met:
9    *
10   * 1. Redistributions of source code must retain the above copyright
11   *    notice, this list of conditions and the following disclaimer.
12   *
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   *
17   * 3. The end-user documentation included with the redistribution, if any,
18   *    must include the following acknowledgment:
19   *
20   *    "This product includes software developed by DBMonster developers
21   *    (http://dbmonster.kernelpanic.pl/)."
22   *
23   *  Alternately, this acknowledgment may appear in the software itself,
24   *  if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The name "DBMonster" must not be used to endorse or promote products
27   *    derived from this software without prior written permission. For
28   *    written permission, please contact piotr.maj@kernelpanic.pl.
29   *
30   * 5. Products derived from this software may not be called "DBMonster",
31   *    nor may "DBMonster" appear in their name, without prior written
32   *    permission of Piotr Maj.
33   *
34   * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37   * IN NO EVENT SHALL THE DBMONSTER DEVELOPERS BE LIABLE FOR ANY DIRECT,
38   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
40   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
42   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
43   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44   * POSSIBILITY OF SUCH DAMAGE.
45   */
46  
47  package pl.kernelpanic.dbmonster.generator;
48  
49  import java.util.ArrayList;
50  import java.util.List;
51  import java.sql.ResultSet;
52  
53  import org.apache.commons.logging.Log;
54  
55  import pl.kernelpanic.dbmonster.DBMonster;
56  import pl.kernelpanic.dbmonster.DBMonsterContext;
57  import pl.kernelpanic.dbmonster.connection.ConnectionProvider;
58  import pl.kernelpanic.dbmonster.connection.Transaction;
59  import pl.kernelpanic.dbmonster.schema.Column;
60  import pl.kernelpanic.dbmonster.schema.Key;
61  
62  /***
63   * The max key generator.
64   *
65   * @author Piotr Maj <piotr.maj@kernelpanic.pl>
66   *
67   * @version $Id: MaxKeyGenerator.html,v 1.1 2007/06/21 08:38:13 sbahloul Exp $
68   */
69  public class MaxKeyGenerator implements KeyGenerator, Initializable {
70  
71      /***
72       * The key.
73       */
74      private Key key = null;
75  
76      /***
77       * Holds a list of columns.
78       */
79      private List columns = new ArrayList();
80  
81      /***
82       * Context.
83       */
84      private DBMonsterContext context = null;
85  
86      /***
87       * The next value to insert.
88       */
89      private long nextId = 0L;
90  
91      /***
92       * Sets the key.
93       *
94       * @param k the key.
95       */
96      public void setKey(final Key k) {
97          key = k;
98      }
99  
100     public Key getKey() {
101         return key;
102     }
103 
104     /***
105      * Returns columns.
106      *
107      * @return a list of columns
108      */
109     public List getColumns() {
110         return columns;
111     }
112 
113     /***
114      * Generates a primary key.
115      *
116      * @return a list of generated <code>Column</code>s.
117      */
118     public List generate() {
119         Column column = (Column) columns.get(0);
120         column.setValue(new Long(nextId++));
121         return columns;
122     }
123 
124     /***
125      * @see Initializable#initialize(DBMonsterContext)
126      */
127     public void initialize(final DBMonsterContext ctx) throws Exception {
128         context = ctx;
129 
130         Log log = (Log) context.getProperty(DBMonster.LOGGER_KEY);
131         if (log.isDebugEnabled()) {
132             log.debug("Initializing generator <" + getClass().getName() + ">.");
133         }
134 
135         ConnectionProvider connProv =
136             (ConnectionProvider) context.getProperty(
137                 DBMonster.CONNECTION_PROVIDER_KEY);
138         Transaction tx = new Transaction(connProv);
139         try {
140             tx.begin();
141             Column column = (Column) columns.get(0);
142             String sql = "SELECT max(" + column.getName() + ") FROM "
143                 + key.getTable().getName();
144 
145             if (log.isDebugEnabled()) {
146                 log.debug(sql);
147             }
148 
149             ResultSet rs = tx.executeQuery(sql);
150             if (rs.next()) {
151                 nextId = rs.getLong(1);
152                 if (log.isDebugEnabled()) {
153                     log.debug("Key generator initial value is: " + nextId);
154                 }
155                 ++nextId;
156             }
157             tx.commit();
158         } catch (Exception e) {
159             if (log.isFatalEnabled()) {
160                 log.fatal(e.getMessage());
161             }
162             tx.abort();
163             throw e;
164         } finally {
165             tx.close();
166         }
167 
168         if (log.isDebugEnabled()) {
169             log.debug("Initialization of generator <"
170                 + getClass().getName() + "> finished.");
171         }
172     }
173 
174     /***
175      * Returns a column name.
176      *
177      * @return the name of the column.
178      */
179     public final String getColumnName() {
180         if (columns.size() == 1) {
181             Column column = (Column) columns.get(0);
182             if (column != null) {
183                 return column.getName();
184             }
185         }
186         return null;
187     }
188 
189     /***
190      * Sets the column name and sets up the column.
191      *
192      * @param name the name of the column.
193      */
194     public final void setColumnName(final String name) {
195         Column column = new Column();
196         column.setName(name);
197         columns.clear();
198         columns.add(column);
199     }
200 }