KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > facility > naming > longid > LongIdManager


1 /**
2  * JORM: an implementation of a generic mapping system for persistent Java
3  * objects. Two mapping are supported: to RDBMS and to binary files.
4  * Copyright (C) 2004 France Telecom R&D
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 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 org.objectweb.jorm.facility.naming.longid;
21
22 import org.objectweb.jorm.api.PAccessor;
23 import org.objectweb.jorm.api.PBinding;
24 import org.objectweb.jorm.api.PClassMapping;
25 import org.objectweb.jorm.api.PException;
26 import org.objectweb.jorm.api.PExceptionNoDSI;
27 import org.objectweb.jorm.api.PMapper;
28 import org.objectweb.jorm.api.PMapCluster;
29 import org.objectweb.jorm.facility.naming.basidir.BasidBinder;
30 import org.objectweb.jorm.facility.naming.generator.LongGen;
31 import org.objectweb.jorm.facility.naming.generator.LongGenIncrMgr;
32 import org.objectweb.jorm.facility.naming.generator.PLongGen;
33 import org.objectweb.jorm.facility.naming.polymorphid.ClassIdAccessor;
34 import org.objectweb.jorm.facility.naming.polymorphid.IdClassAccessor;
35 import org.objectweb.jorm.naming.api.PBinder;
36 import org.objectweb.jorm.naming.api.PExceptionNaming;
37 import org.objectweb.jorm.naming.api.PNameCoder;
38 import org.objectweb.jorm.naming.api.PNamingContext;
39
40 /**
41  * Is a manager helping the used of LongId identifier. A LongId is
42  * composed of two parts. The high bits describe the class identifier, whereas
43  * the low bits describes the object instance identifier. The limit between both
44  * parts are defined are building time (constructor).
45  *
46  * The allocation of identifiers is done through long generator.
47  *
48  * The manager permits to allocates PBinder and PNamingContext for normal class
49  * and generic class.
50  *
51  * @author S.Chassande-Barrioz
52  */

53 public class LongIdManager {
54
55     /**
56      * Is the default size of the class identifier in term of number of bits
57      */

58     public final static int DEFAULT_CID_SIZE = 20;
59
60     /**
61      * is the number of bits of an identifier. It is equal to the number of
62      * bits of a long value (64)
63      */

64     public final static int LONG_SIZE = 64;
65
66     /**
67      * Is the name of the persistent class used to load/store the association
68      * between a class name and its class identifier
69      */

70     public static final String JavaDoc CLASS_ID_NAME =
71         "org.objectweb.jorm.facility.naming.polymorphid.ClassId";
72
73     /**
74      * Is the name of the persistent class used to load/store the association
75      * between a class identifier and its class name.
76      */

77     public static final String JavaDoc ID_CLASS_NAME =
78         "org.objectweb.jorm.facility.naming.polymorphid.IdClass";
79
80     /**
81      * The the manager of generator. It used to allocate object id generator
82      * for each binder and also to allocate the unique class identifier
83      * generator.
84      */

85     private LongGenIncrMgr idGenMgr;
86
87     /**
88      * Is the class identifier generator.
89      */

90     private LongGen classIdGen;
91
92     /**
93      * Is the mapper where the generator are persistent.
94      */

95     private PMapper mapper;
96
97     /**
98      * is the number of bits allocated for the class identifier among the
99      * number of bits of a long value (64).
100      */

101     private int cidSize = DEFAULT_CID_SIZE;
102
103     /**
104      * Builds a LongIdManager with the default class identifier size.
105      * IMMPORTANT: a mapper must be assigned later.
106      */

107     public LongIdManager() {
108         setCidSize(DEFAULT_CID_SIZE);
109     }
110
111     /**
112      * Builds and intializes a LongIdManager with the default class identifier
113      * size.
114      * @param mapper is the mapper where the generator are persistent.
115      */

116     public LongIdManager(PMapper mapper) throws PException {
117         this(mapper, DEFAULT_CID_SIZE);
118     }
119
120     /**
121      * Builds and intializes a LongIdManager with a particular class identifier
122      * size.
123      * @param mapper is the mapper where the generator are persistent.
124      * @param cidSize is the number of bits allocated for the class identifier among the
125      * number of bits of a long value (64).
126      */

127     public LongIdManager(PMapper mapper, int cidSize) throws PException {
128         setCidSize(cidSize);
129         setPMapper(mapper);
130     }
131
132     public int getCidSize() {
133         return cidSize;
134     }
135
136     public void setCidSize(int cidSize) {
137         this.cidSize = cidSize;
138     }
139
140     public PMapper getMapper() {
141         return mapper;
142     }
143
144     /**
145      * Instanciates and initializes a LongGenMgr
146      * Allocates a class identifier generator
147      * @param mapper the mapper where the id generator are stored
148      * @throws PException if no LongGenMgr has been found in the specified
149      * mapper.
150      */

151     public void setPMapper(PMapper mapper) throws PException {
152         if (mapper == null) {
153             throw new PExceptionNaming("No mapper specified");
154         }
155         this.mapper = mapper;
156         try {
157             idGenMgr = (LongGenIncrMgr)
158                 Class.forName(getLongGenMgr()).newInstance();
159         } catch (Exception JavaDoc e) {
160             throw new PExceptionNaming(e,
161                 "Impossible to instanciate the LongGenMgr "
162                 + getLongGenMgr());
163         }
164         idGenMgr.init(mapper, PClassMapping.CREATE_STRUCTURE_IF_NEEDED);
165         classIdGen = idGenMgr.getLongGen(CLASS_ID_NAME, null);
166
167         PBinder binder = new BasidBinder(PNamingContext.CTSTRING);
168         String JavaDoc cn = mapper.cn2mn(CLASS_ID_NAME) + PMapper.PCLASSMAPPINGAPPENDER;
169         PClassMapping pcm;
170         try {
171             pcm = (PClassMapping) Class.forName(cn).newInstance();
172         } catch (Exception JavaDoc e) {
173             throw new PException(e);
174         }
175         pcm.setPBinder(binder);
176         binder.setPClassMapping(pcm);
177         mapper.map(pcm);
178         PMapCluster cl = mapper.getPMapCluster(pcm.getClassName());
179         cl.createMappingStructures(false);
180     }
181
182     /**
183      * Calculates the class name of the LongGenMgr from the mapper name. Indeed
184      * the class is the generated PClassMapping of the persistent class
185      * org.objectweb.jorm.facility.naming.generator.LongGenIncr.
186      */

187     private String JavaDoc getLongGenMgr() {
188         String JavaDoc mn = mapper.getMapperName();
189         int idx = mn.indexOf('.');
190         if (idx != -1) {
191             mn = mn.substring(0, idx);
192         }
193         return "org.objectweb.jorm.facility.naming.generator."
194             + mn + ".LongGenIncrMapping";
195     }
196
197     /**
198      * Allocates a new PBinder for gen class. This PBinder can be used as
199      * PNameCoder too.
200      */

201     public PBinder newGenClassPBinder() throws PException {
202         return new BasidBinder(PNameCoder.CTLONG, -1);
203     }
204
205     /**
206      * Allocates a new PNamingcontext for a normal persistent class (not a
207      * generic class).
208      */

209     public PNamingContext newClassPNamingContext() throws PException {
210         return new LongIdPNC(cidSize);
211     }
212
213     /**
214      * Allocates a new PBinder for a normal persistent class (not a generic
215      * class).
216      * @param className is the name of the persistent class
217      * @param conn is a way to access the data support. If the value is null,
218      * a connection is allocated from the mapper.
219      * @throws PException
220      */

221     public PBinder newClassPBinder(String JavaDoc className, Object JavaDoc conn) throws PException {
222         if (mapper == null) {
223             throw new PException("The LongIdManager has not been configured, a PMapper is required");
224         }
225         Object JavaDoc connection = conn;
226         if (conn == null) {
227             connection = mapper.getConnection();
228         }
229         try {
230             LongGen lg = new CompositePLongGen(
231                 (PLongGen) idGenMgr.getLongGen(className, connection),
232                 getCID(className, connection),
233                 cidSize);
234             LongIdBinder lib = new LongIdPBinder();
235             lib.setACFLid(lg);
236             return lib;
237         } finally {
238             if (conn == null) {
239                 mapper.closeConnection(connection);
240             }
241         }
242     }
243
244
245     /**
246      * Fetches the identifier (long value) of a normal persistent class.
247      * If no value has been already allocated (nothing store in database), then
248      * a new value is allocated and saved through the class identifier
249      * generator.
250      *
251      * @param className is the name of the persistent class.
252      * @param conn is a way to access the data support. If the value is null,
253      * a connection is allocated from the mapper.
254      * @return the long value representing the persistent class.
255      * @throws PException
256      */

257     private long getCID(String JavaDoc className, Object JavaDoc conn) throws PException {
258         PClassMapping pcm = mapper.lookup(CLASS_ID_NAME);
259         PBinding binding = pcm.createPBinding();
260         binding.bind(pcm.getPBinder().decodeString(className));
261         Object JavaDoc connection = conn;
262         if (conn == null)
263             connection = mapper.getConnection();
264         CIDAccessor acc = new CIDAccessor(className);
265         try {
266             binding.read(connection, acc);
267         } catch (PExceptionNoDSI e) {
268             binding.export(connection, className);
269             acc.cid = classIdGen.genId(connection);
270             binding.write(connection, acc);
271         } finally {
272             if (conn == null) {
273                 mapper.closeConnection(connection);
274             }
275         }
276         binding.unbind();
277         return acc.cid;
278     }
279
280     /**
281      * Is an accessor permitting to store/load the assocaition between a
282      * persistent class name (String) and the class identifier (long).
283      *
284      */

285     private class CIDAccessor implements PAccessor, ClassIdAccessor, IdClassAccessor {
286         public long cid;
287         public String JavaDoc className;
288
289         public CIDAccessor(String JavaDoc className) {
290             this.className = className;
291         }
292
293         public CIDAccessor(long cid) {
294             this.cid = cid;
295         }
296
297         public Object JavaDoc getMemoryInstance() {
298             return this;
299         }
300
301         //Accessors to the classId field
302
public void paSetClassId(long val) throws PException {
303             cid = val;
304         }
305
306         public long paGetClassId() throws PException {
307             return cid;
308         }
309
310         //Accessors to the className field
311
public void paSetClassName(String JavaDoc val) throws PException {
312             className = val;
313         }
314
315         public String JavaDoc paGetClassName() throws PException {
316             return className;
317         }
318     }
319 }
320
Popular Tags