KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > naming > lib > RdbSequenceNamingManager


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.naming.lib;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Properties JavaDoc;
25
26 import javax.jdo.datastore.Sequence;
27
28 import org.objectweb.jorm.api.PException;
29 import org.objectweb.jorm.facility.naming.generator.LongGen;
30 import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceBinder;
31 import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequencePName;
32 import org.objectweb.jorm.metainfo.api.CommonClassMapping;
33 import org.objectweb.jorm.metainfo.api.GenClassRef;
34 import org.objectweb.jorm.metainfo.api.Manager;
35 import org.objectweb.jorm.metainfo.api.MetaObject;
36 import org.objectweb.jorm.metainfo.api.NameDef;
37 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
38 import org.objectweb.jorm.metainfo.api.Reference;
39 import org.objectweb.jorm.naming.api.PBinder;
40 import org.objectweb.jorm.naming.api.PName;
41 import org.objectweb.jorm.naming.api.PNameCoder;
42 import org.objectweb.jorm.type.api.PType;
43 import org.objectweb.jorm.type.api.PTypeSpace;
44 import org.objectweb.speedo.api.SpeedoException;
45 import org.objectweb.speedo.generation.jorm.JormMIMappingBuilder;
46 import org.objectweb.speedo.generation.lib.NamingRules;
47 import org.objectweb.speedo.mapper.api.JormFactory;
48 import org.objectweb.speedo.metadata.SpeedoClass;
49 import org.objectweb.speedo.metadata.SpeedoField;
50 import org.objectweb.speedo.naming.api.MIBuilderHelper;
51 import org.objectweb.speedo.naming.api.NamingManager;
52 import org.objectweb.speedo.sequence.lib.SpeedoSequence;
53 import org.objectweb.speedo.sequence.lib.SpeedoSequenceBinder;
54 import org.objectweb.speedo.tools.StringReplace;
55 import org.objectweb.util.monolog.api.BasicLevel;
56
57 /**
58  *
59  * @author S.Chassande-Barrioz
60  */

61 public class RdbSequenceNamingManager
62     extends NamingManagerHelper
63     implements NamingManager {
64
65     private final static String JavaDoc SEQUENCE_ID ="sid";
66     private final static String JavaDoc BINDER_CLASS_NAME
67             = RdbSequenceBinder.class.getName();
68     private final static String JavaDoc SPEEDO_BINDER_CLASS_NAME
69             = SpeedoSequenceBinder.class.getName();
70     public final static int SEQ_NAME_IDX = 4;
71     public final static int SEQ_INCREMENT_IDX = 5;
72     public final static int SEQ_STARTID_IDX = 6;
73     public final static int SEQ_CACHE_IDX = 7;
74     public final static int SEQ_ALLOCATOR_IDX = 8;
75
76
77
78     public boolean canManage(SpeedoClass sc) {
79         if (sc.datastoreSequence != null) {
80             return true;
81         }
82         return false;
83     }
84
85     // IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
86
//---------------------------------------------------------------//
87

88     public PName decode(PNameCoder pnc,
89                         Object JavaDoc oid,
90                         Class JavaDoc clazz,
91                         JormFactory jf) throws PException {
92         if (oid instanceof String JavaDoc) {
93             String JavaDoc stroid = (String JavaDoc) oid;
94             if (pnc != null) {
95                 if (pnc instanceof RdbSequenceBinder) {
96                     int idx = stroid.indexOf(SEP);
97                     if (idx != -1) {
98                         //The oid contains the class name
99
return pnc.decodeString(stroid.substring(idx + SEP.length()));
100                     } else {
101                         //The oid must decoded directly
102
return pnc.decodeString(stroid);
103                     }
104
105                 } else {
106                     //The pnc is not a RdbSequenceBinder, then the oid cannot be managed
107
return null;
108                 }
109             } else {
110                 //No pnc specified
111
int idx = stroid.indexOf(SEP);
112                 ClassLoader JavaDoc cl = null;
113                 String JavaDoc fqcn;
114                 if (idx != -1) {
115                     //The oid contains the class name
116
fqcn = stroid.substring(0, idx);
117                 } else if (clazz != null) {
118                     fqcn = clazz.getName();
119                 } else {
120                     //The oid cannot be managed
121
return null;
122                 }
123                 cl = jf.getClass().getClassLoader();
124                 if (cl == null) {
125                     cl = ClassLoader.getSystemClassLoader();
126                 }
127                 try {
128                     pnc = jf.getPBinder(fqcn, cl);
129                 } catch (Exception JavaDoc e) {
130                     return null;
131                 }
132                 return (pnc instanceof RdbSequenceBinder
133                     ? pnc.decodeString(stroid.substring(idx + SEP.length()))
134                     : null);
135             }
136         } else if (pnc instanceof RdbSequenceBinder){
137             if (oid instanceof Integer JavaDoc) {
138                 pnc.decodeLong(((Integer JavaDoc) oid).intValue());
139             } else if (oid instanceof Long JavaDoc) {
140                 pnc.decodeLong(((Long JavaDoc) oid).longValue());
141             }
142         }
143         return null;
144     }
145
146     public Object JavaDoc encode(PName pn) throws PException {
147         if (pn instanceof RdbSequencePName) {
148             return pn.getPNameManager().getPType().getJormName()
149                     + SEP + pn.encodeString();
150         }
151         return null;
152     }
153
154     protected String JavaDoc getName() {
155         return SEQUENCE_ID;
156     }
157
158     public PBinder getPBinder(String JavaDoc className,
159                               String JavaDoc hints,
160                               ClassLoader JavaDoc cl,
161                               byte mappingStructureRule,
162                               Map JavaDoc cn2binder,
163                               Map JavaDoc cn2pnc) throws PException {
164         SpeedoSequenceBinder binder = (SpeedoSequenceBinder) super.getPBinder(
165             className, hints, cl, mappingStructureRule, cn2binder, cn2pnc);
166         String JavaDoc[] tokens = getTokens(hints);
167         if (tokens[SEQ_NAME_IDX].length() > 0) {
168             if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
169                 logger.log(BasicLevel.DEBUG, "Sequence name: " + tokens[SEQ_NAME_IDX]);
170             }
171             String JavaDoc sequencePrefix = (className.lastIndexOf('.') != -1) ? className.substring(0, className.lastIndexOf('.')+1):"";
172             sequencePrefix = StringReplace.replaceString("/", "", sequencePrefix);
173             Sequence sequence = pmf.getSequenceManager().getSequence(sequencePrefix + tokens[SEQ_NAME_IDX]);
174             if (sequence == null) {
175                 throw new PException("Wrong sequence name: " + sequencePrefix + tokens[SEQ_NAME_IDX]);
176             }
177             LongGen longGen = ((SpeedoSequence) sequence).getLongGen();
178             /*if (longGen instanceof RdbSequenceLongGen) {
179                 ((RdbSequenceLongGen) longGen).setLogger(logger);
180                 binder.setSequenceHelper((RdbSequenceLongGen) longGen);
181             }*/

182             binder.setSequence(sequence);
183         }
184         return binder;
185     }
186
187     public void getJormNamingConfig(NameDef nd,
188                                     SpeedoClass targetClass,
189                                     MetaObject sourceMO,
190                                     String JavaDoc key,
191                                     Properties JavaDoc result) throws SpeedoException{
192         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
193         sb.append(SEQUENCE_ID);
194
195         sb.append(HINTS_SEP);
196         sb.append(SPEEDO_BINDER_CLASS_NAME);
197
198         SpeedoClass ancestor = targetClass.getAncestor();
199         String JavaDoc ancestorClassName;
200         String JavaDoc pncClassName;
201         if (!(sourceMO instanceof GenClassRef) //For a Genclass ref or identifier
202
&& (ancestor != null // has supper class
203
|| !targetClass.jormclass.getSubClasses().isEmpty()) // has sub class
204
) {
205             if (ancestor == null) {
206                 ancestor = targetClass;
207             }
208             ancestorClassName = ancestor.getFQName();
209             try {
210                 if (targetClass.jormclass.getSubClasses().isEmpty()) {
211                     pncClassName = SPEEDO_BINDER_CLASS_NAME;
212                 } else if (targetClass.jormclass.detectFilterElementNotInPK(targetClass.jormclass.getInheritanceFilter(nd), nd)) {
213                     //if has child(ren)
214
//and one of the fields of the filter is not in the primary key,
215
//use a PolymorphicPNC
216
pncClassName = POLYMORPHIC_PNC;
217                 } else {
218                     //use a kfpnc
219
pncClassName = NamingRules.kfpncName(ancestor.getFQName());
220                 }
221             } catch (Exception JavaDoc e) {
222                 logger.log(BasicLevel.ERROR, "Error while retrieving the inheritance filter of the namedef:" + nd.toString());
223                 throw new SpeedoException("Error while retrieving the inheritance filter of the namedef:" + nd.toString(), e);
224             }
225         } else {
226             ancestorClassName = targetClass.getFQName();
227             pncClassName = SPEEDO_BINDER_CLASS_NAME;
228         }
229         //specify the pnc className
230
sb.append(HINTS_SEP);
231         sb.append(pncClassName);
232
233         //specify the className of the ancestor
234
sb.append(HINTS_SEP);
235         sb.append(ancestorClassName);
236
237
238         //sequence name
239
sb.append(HINTS_SEP);
240         if (targetClass.datastoreSequence != null) {
241             sb.append(targetClass.datastoreSequence);
242         }
243         result.setProperty(key, sb.toString());
244      }
245
246     public String JavaDoc getPNameHints(SpeedoClass sc, NameDef nd) {
247         return "null";
248     }
249
250     public String JavaDoc getGCPNameHints(SpeedoClass sc, NameDef nd) {
251         return "proxy.getPName()";
252     }
253
254     /**
255      * The auto incremented field used as identifier can be a visble or
256      * an hidden field. In case the field is visible, the
257      */

258     public void fillNameDef(MIBuilderHelper mibh,
259                             Manager manager,
260                             NameDef nd,
261                             SpeedoClass tsc,
262                             SpeedoClass ssc,
263                             MetaObject mo,
264                             Reference ref,
265                             CommonClassMapping hcm,
266                             JormMIMappingBuilder mb,
267                             boolean isIdentifier,
268                             boolean isInGenClass,
269                             boolean createField,
270                             Collection JavaDoc createdMOs) throws SpeedoException, PException {
271         Iterator JavaDoc it = tsc.jdoField.values().iterator();
272         SpeedoField sf = null;
273         ArrayList JavaDoc al = null;
274         while(it.hasNext()) {
275             SpeedoField _sf = (SpeedoField) it.next();
276             if (_sf.primaryKey) {
277                 if (sf != null) {
278                     if (al == null) {
279                         al = new ArrayList JavaDoc();
280                     }
281                     al.add(_sf.name);
282                 } else {
283                     sf = _sf;
284                 }
285             }
286         }
287         if (al != null) {
288             al.add(sf);
289             throw new SpeedoException(
290                     "Impossible to use an auto incremented identifier if " +
291                     "several fields have been marked as primary-key " + al
292                     + " in the class '" + tsc.getFQName() + "'.");
293         }
294         String JavaDoc fieldName = null;
295         fieldName = mibh.getNameDefFieldPrefix(ref, isIdentifier, isInGenClass);
296         PType newLongFieldType = PTypeSpace.OBJLONG;
297         if (sf == null) {
298             fieldName += "id_";
299         } else {
300             if ("java.lang.Long".equals(sf.type()) || "Long".equals(sf.type())) {
301                 newLongFieldType = PTypeSpace.OBJLONG;
302             } else if ("long".equals(sf.type())) {
303                 newLongFieldType = PTypeSpace.LONG;
304             } else {
305                 throw new SpeedoException(
306                         "Impossible to use an auto incremented identifier: " +
307                         "the field type of '" + sf.name + "' is '" + sf.type()
308                         + "' and 'java.lang.Long' or long is expected (class '"
309                         + tsc.getFQName() + "'.");
310             }
311             if (!isInGenClass && fieldName.length() == 0) {
312                 //The field already exists and its mapping is defined when primitive
313
// fields are mapped.
314
createField = false;
315             }
316             fieldName += sf.name;
317         }
318         PrimitiveElement id = null;
319         if (createField) {
320             id = mibh.createNameDefField(mo, fieldName, newLongFieldType);
321         } else {
322             id = mibh.getPrimitiveField(mo, fieldName);
323             if (id == null) {
324                 throw new SpeedoException(
325                         mibh.getErrorMessage(tsc, mo, ref)
326                         + " Impossible to get the field '" + fieldName + "'");
327             }
328         }
329         nd.setFieldName(fieldName);
330         if (createField && (mb != null)) {
331             mb.createNameDefMapping(hcm, nd, ssc, isIdentifier, isInGenClass);
332         }
333     }
334
335     public NamingField[] getNamingfields(SpeedoClass sc) throws PException {
336         Iterator JavaDoc it = sc.jdoField.values().iterator();
337         while(it.hasNext()) {
338             SpeedoField sf = (SpeedoField) it.next();
339             if (sf.primaryKey) {
340                 Class JavaDoc fieldType;
341                 PType fieldPType;
342                 if ("java.lang.Long".equals(sf.type()) || "Long".equals(sf.type())) {
343                     fieldType = Long JavaDoc.class;
344                     fieldPType = PTypeSpace.OBJLONG;
345                 } else if ("long".equals(sf.type())) {
346                     fieldType = Long.TYPE;
347                     fieldPType = PTypeSpace.LONG;
348                 } else {
349                     throw new PException(
350                             "Impossible to use an auto incremented identifier: " +
351                             "the field type of '" + sf.name + "' is '" + sf.type()
352                             + "' and 'java.lang.Long' or 'long' is expected (class '"
353                             + sc.getFQName() + "'.");
354                 }
355                 return new NamingField[] {
356                     new NamingField(sf.name, fieldType, "lid", fieldPType)};
357             }
358         }
359         return null;
360     }
361 }
362
Popular Tags