Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: ojb/broker/util/sequence/SequenceManagerDefaultImpl.java


1   /*
2    * ObJectRelationalBridge - Bridging Java Objects and Relational Databases
3    * http://objectbridge.sourceforge.net
4    * Copyright (C) 2000, 2001 Thomas Mahler, et al.
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19   */
20  package ojb.broker.util.sequence;
21  
22  import ojb.broker.PersistenceBrokerException;
23  import ojb.broker.PersistenceBrokerSQLException;
24  import ojb.broker.metadata.ClassDescriptor;
25  import ojb.broker.query.QueryByExample;
26  import ojb.broker.singlevm.PersistenceBrokerImpl;
27  import ojb.broker.util.logging.*;
28  
29  import java.sql.ResultSet;
30  import java.sql.SQLException;
31  import java.sql.Statement;
32  
33  /**
34   * A simple SequenceManager. This class is responsible for creating new unique ID's for primary columns
35   * containing integer values.
36   * The SequenceManager is aware of extends, that is: if you ask for an uid for an Interface with several implementor classes,
37   * or a baseclass with several subclasses the returned uid will unique accross all tables representing
38   * objects of the extent in question.
39   * @author: thma
40   */
41  public class SequenceManagerDefaultImpl implements SequenceManager
42  {
43  
44      /**
45       * reference to the PersistenceBroker
46       */
47      protected PersistenceBrokerImpl broker;
48  
49      /**
50       * singleton instance of the SequenceManager
51       */
52      private static SequenceManagerDefaultImpl _instance;
53  
54      /**
55       *
56       * Public constructor
57       *
58       */
59      public SequenceManagerDefaultImpl(PersistenceBrokerImpl broker)
60      {
61          this.broker = broker;
62      }
63  
64  
65      /**
66       * lookup current maximum value for fieldName in table cld.getTableName()
67       */
68      private int getMaxIdForClass(ClassDescriptor cld, String fieldName) throws PersistenceBrokerException
69      {
70          int result = 0;
71          ResultSet rs = null;
72          Statement stmt = null;
73          try
74          {
75              String table = cld.getFullTableName();
76              String column = cld.getFieldDescriptorByName(fieldName).getColumnName();
77              String sql = "SELECT MAX(" + column + ") FROM " + table;
78              stmt = broker.getStatementManager().getGenericStatement(cld);
79              rs = stmt.executeQuery(sql);
80              rs.next();
81              result = rs.getInt(1);
82  
83          }
84          catch (Throwable t)
85          {
86              LoggerFactory.getDefaultLogger().error(t);
87              throw new PersistenceBrokerException(t);
88          }
89          finally
90          {
91              try
92              {
93                  rs.close();
94                  stmt.close();
95              }
96              catch (SQLException e)
97              {
98                  LoggerFactory.getDefaultLogger().error(e);
99                  throw new PersistenceBrokerSQLException(e);
100             }
101             return result;
102         }
103     }
104 
105     /**
106      *
107      */
108     private synchronized int getNextId(Class clazz, String fieldName) throws PersistenceBrokerException
109     {
110         // check if there is an entry for this class
111         SequenceEntry tmp = new SequenceEntry();
112         tmp.setClassname(clazz.getName());
113         tmp.setFieldname(fieldName);
114         SequenceEntry entry = (SequenceEntry) broker.getObjectByQuery(new QueryByExample(tmp));
115         // if no entry found, build a new one first:
116         if (entry == null)
117         {
118             int lastId = getMaxForExtent(clazz, fieldName);
119             entry = new SequenceEntry(clazz.getName(), fieldName, lastId);
120         }
121         // compute next uid, update the entry, store it and return
122         int nextId = entry.getCurrent() + 1;
123         entry.setCurrent(nextId);
124         broker.store(entry);
125         return nextId;
126     }
127 
128     /**
129      * returns a unique int for class clazz and field fieldName.
130      * the returned uid is unique accross all tables in the extent of clazz.
131      */
132     public int getUniqueId(Class clazz, String fieldName)
133     {
134         return getNextId(clazz, fieldName);
135     }
136 
137     /**
138      * lookup all tables in extent clazz to find the current maximum value for fieldName
139      */
140     protected int getMaxForExtent(Class clazz,
141                                   String fieldName) throws PersistenceBrokerException
142     {
143         int max = 0;
144         ClassDescriptor cld = broker.getClassDescriptor(clazz);
145         // if class is no Interface we have to search its directly mapped table
146         if (!cld.isInterface())
147         {
148             int tmp = getMaxIdForClass(cld, fieldName);
149             if (tmp > max)
150             {
151                 max = tmp;
152             }
153         }
154         // if class is an extent we have to search through its subclasses
155         if (cld.isExtent())
156         {
157             java.util.Vector extentClasses = cld.getExtentClasses();
158             for (int i = 0; i < extentClasses.size(); i++)
159             {
160                 Class ec = (Class) extentClasses.get(i);
161                 cld = broker.getClassDescriptor(ec);
162                 int tmp = getMaxIdForClass(cld, fieldName);
163                 if (tmp > max)
164                 {
165                     max = tmp;
166                 }
167             }
168         }
169         return max;
170     }
171 
172     /**
173      * returns a unique String for class clazz and field fieldName.
174      * the returned uid is unique accross all tables in the extent of clazz.
175      *
176      */
177     public String getUniqueString(Class clazz, String fieldName)
178     {
179         return Integer.toString(getUniqueId(clazz, fieldName));
180     }
181 
182     /**
183      * returns a unique long value for class clazz and field fieldName.
184      * the returned number is unique accross all tables in the extent of clazz.
185      */
186     public long getUniqueLong(Class clazz, String fieldName)
187     {
188         return (long) getUniqueId(clazz, fieldName);
189     }
190 
191     /**
192      * returns a unique Object for class clazz and field fieldName.
193      * the returned Object is unique accross all tables in the extent of clazz.
194      */
195     public Object getUniqueObject(Class clazz, String fieldName)
196     {
197         return getUniqueString(clazz, fieldName);
198     }
199 }