KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.objectweb.perseus.cache.api.CacheManager;
21 import org.objectweb.speedo.naming.api.NamingManager;
22 import org.objectweb.speedo.naming.api.MIBuilderHelper;
23 import org.objectweb.speedo.pm.api.ProxyManagerFactory;
24 import org.objectweb.jorm.facility.naming.olongid.LongIdManager;
25 import org.objectweb.jorm.facility.naming.olongid.LongIdBinder;
26 import org.objectweb.jorm.facility.naming.olongid.LongIdPName;
27 import org.objectweb.jorm.facility.naming.olongid.LongIdPNC;
28 import org.objectweb.speedo.metadata.SpeedoClass;
29 import org.objectweb.speedo.metadata.SpeedoIdentity;
30 import org.objectweb.speedo.metadata.SpeedoExtension;
31 import org.objectweb.speedo.metadata.SpeedoField;
32 import org.objectweb.speedo.api.SpeedoProperties;
33 import org.objectweb.speedo.api.SpeedoException;
34 import org.objectweb.speedo.mapper.api.JormFactory;
35 import org.objectweb.speedo.generation.jorm.JormMIMappingBuilder;
36 import org.objectweb.speedo.generation.lib.NamingRules;
37 import org.objectweb.util.monolog.api.Logger;
38 import org.objectweb.util.monolog.api.BasicLevel;
39 import org.objectweb.jorm.naming.api.PName;
40 import org.objectweb.jorm.naming.api.PNameCoder;
41 import org.objectweb.jorm.naming.api.PBinder;
42 import org.objectweb.jorm.naming.api.PNamingContext;
43 import org.objectweb.jorm.api.PClassMapping;
44 import org.objectweb.jorm.api.PException;
45 import org.objectweb.jorm.api.PMapper;
46 import org.objectweb.jorm.metainfo.api.NameDef;
47 import org.objectweb.jorm.metainfo.api.MetaObject;
48 import org.objectweb.jorm.metainfo.api.Manager;
49 import org.objectweb.jorm.metainfo.api.Reference;
50 import org.objectweb.jorm.metainfo.api.CommonClassMapping;
51 import org.objectweb.jorm.metainfo.api.GenClassRef;
52 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
53 import org.objectweb.jorm.metainfo.api.CompositeName;
54 import org.objectweb.jorm.metainfo.api.NameRef;
55 import org.objectweb.jorm.metainfo.api.ScalarField;
56 import org.objectweb.jorm.type.api.PTypeSpace;
57 import org.objectweb.jorm.type.api.PType;
58 import org.objectweb.medor.expression.api.Expression;
59 import org.objectweb.medor.expression.api.ExpressionException;
60 import org.objectweb.medor.expression.lib.DivideBy;
61 import org.objectweb.medor.expression.lib.BasicOperand;
62 import org.objectweb.medor.expression.lib.BasicParameterOperand;
63 import org.objectweb.medor.expression.lib.Round;
64
65 import java.util.Properties JavaDoc;
66 import java.util.Map JavaDoc;
67 import java.util.Collection JavaDoc;
68 import java.util.Iterator JavaDoc;
69 import java.util.ArrayList JavaDoc;
70
71 /**
72  *
73  * @author S.Chassande-Barrioz
74  */

75 public class OLongIdNamingManager
76     extends LongIdManager
77     implements NamingManager {
78
79     private final static String JavaDoc _LONG_ID_NAME
80         = "org.objectweb.jorm.facility.naming.olongid.LongId";
81     private final static String JavaDoc _LONG_ID_LID = "olid";
82     private final static String JavaDoc BINDER_FOR_CLASS = "c";
83     private final static String JavaDoc BINDER_FOR_GENCLASS = "gc";
84     private final static String JavaDoc HIDDEN_LID_FIELD_NAME = "jdolid";
85
86     private Logger logger;
87     private PMapper mapper;
88     private ProxyManagerFactory pmf;
89
90     protected String JavaDoc LONG_ID_NAME() {
91         return _LONG_ID_NAME;
92     }
93     
94     protected String JavaDoc LONG_ID_LID() {
95         return _LONG_ID_LID;
96     }
97     
98     protected PType getFieldType() {
99         return PTypeSpace.OBJLONG;
100     }
101     
102     protected BasicOperand getBasicOperand() {
103         return new BasicOperand(new Long JavaDoc(1l << 44), PTypeSpace.OBJLONG);
104     }
105     
106     protected boolean checkFieldType(String JavaDoc type) {
107         return "Long".equals(type) || "java.lang.Long".equals(type);
108     }
109     
110     
111     public void init() throws PException {
112         if (getMapper() != null) {
113             return;
114         }
115         if (mapper == null) {
116             throw new PException("No mapper assigned");
117         }
118         super.setPMapper(mapper);
119         mapper = null;
120     }
121
122     // IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
123
//---------------------------------------------------------------//
124
public void setPMapper(PMapper mapper) throws PException {
125         this.mapper = mapper;
126     }
127
128     public void setPmf(ProxyManagerFactory pmf) {
129         
130     }
131     
132     public boolean supportPNamingcontext() {
133         return true;
134     }
135
136     public boolean canManage(SpeedoClass sc) {
137         if (sc.identityType == SpeedoIdentity.CONTAINER_ID && sc.datastoreSequence == null) {
138             SpeedoExtension se = sc.getExtension(
139                     SpeedoProperties.VENDOR_NAME, SpeedoProperties.ID);
140             return se != null
141                 && SpeedoProperties.ID_OLONG.equalsIgnoreCase(se.value);
142         } else {
143             return false;
144         }
145     }
146
147     public boolean canProvidePBinder(Object JavaDoc hints, ClassLoader JavaDoc classLoader) {
148         return NamingManagerHelper
149             .getBinderClassNameFromHints(hints, LONG_ID_LID()) != null;
150     }
151
152     public boolean canProvidePNamingContext(Object JavaDoc hints, ClassLoader JavaDoc classLoader) {
153         return NamingManagerHelper
154             .getPNCClassNameFromHints(hints, LONG_ID_LID()) != null;
155     }
156
157     public Object JavaDoc encode(PName pn) throws PException {
158         if (pn instanceof LongIdPName) {
159             return pn.getPNameManager().getPType().getJormName()
160                     + SEP + pn.encodeLong();
161         }
162         return null;
163     }
164
165     public PName decode(PNameCoder pnc,
166                         Object JavaDoc oid,
167                         Class JavaDoc clazz,
168                         JormFactory jf) throws PException {
169         if (oid instanceof String JavaDoc) {
170             String JavaDoc stroid = (String JavaDoc) oid;
171             int idx = stroid.indexOf(SEP);
172             if (pnc != null) {
173                 if (pnc instanceof LongIdBinder
174                         || pnc instanceof LongIdManager) {
175                     String JavaDoc idStr = stroid;
176                     if (idx != -1) {
177                         //The oid contains the class name
178
idStr = stroid.substring(idx + SEP.length());
179                     }
180                     return pnc.decodeOlong(Long.valueOf(idStr));
181
182                 } else {
183                     //The pnc is not a well known pnc, then the oid cannot be managed
184
return null;
185                 }
186             } else {
187                 //No pnc specified
188
if (idx != -1) {
189                     //The oid contains the class name
190
String JavaDoc fqcn = stroid.substring(0, idx);
191                     ClassLoader JavaDoc cl = getClass().getClassLoader();
192                     if (cl == null) {
193                         cl = ClassLoader.getSystemClassLoader();
194                     }
195                     try {
196                         pnc = jf.getPNamingContext(fqcn, cl);
197                     } catch (Exception JavaDoc e) {
198                         return null;
199                     }
200                     if (pnc instanceof LongIdBinder
201                             || pnc instanceof LongIdPNC) {
202                         return pnc.decodeOlong(
203                             Long.valueOf(
204                                 stroid.substring(idx + SEP.length())));
205                     } else {
206                         return null;
207                     }
208                 } else {
209                     //The oid cannot be managed
210
return null;
211                 }
212             }
213         }
214         return null;
215     }
216
217     public void setLogger(Logger logger) {
218         this.logger = logger;
219     }
220
221     public String JavaDoc getPNameHints(SpeedoClass sc, NameDef nd) {
222         return "null";
223     }
224
225     public String JavaDoc getGCPNameHints(SpeedoClass sc, NameDef nd) {
226         return "new Long(proxy.getPName().encodeLong())";
227     }
228
229     public NamingManager.NamingField[] getNamingfields(SpeedoClass sc) {
230         Iterator JavaDoc it = sc.jdoField.values().iterator();
231         while (it.hasNext()) {
232             SpeedoField sf = (SpeedoField) it.next();
233             if (sf.primaryKey) {
234                 return new NamingField[]{
235                     new NamingField(sf.name, Long JavaDoc.class, "lid", getFieldType())};
236             }
237         }
238         return null;
239     }
240
241     public void fillNameDef(MIBuilderHelper mibh,
242                             Manager manager,
243                             NameDef nd,
244                             SpeedoClass tsc,
245                             SpeedoClass ssc,
246                             MetaObject mo,
247                             Reference ref,
248                             CommonClassMapping hcm,
249                             JormMIMappingBuilder mb,
250                             boolean isIdentifier,
251                             boolean isInGenClass,
252                             boolean createField,
253                             Collection JavaDoc createdMOs) throws SpeedoException, PException {
254         SpeedoField sf = fetchUniqueLongPKField(tsc);
255         boolean debug = logger.isLoggable(BasicLevel.DEBUG);
256         if (debug) {
257             logger.log(BasicLevel.DEBUG, "LongIdNaming: Filling the name def: "
258                 + "\n\tsource class=" + (ssc == null ? null : ssc.getFQName())
259                 + "\n\ttarget class=" + (tsc == null ? null : tsc.getFQName())
260                 + "\n\tmo=" + mo
261                 + "\n\treference=" + ref
262                 + "\n\tisIdentifier=" + isIdentifier
263                 + "\n\tisInGenClass=" + isInGenClass
264                 + "\n\tcreateField=" + createField
265                 + "\n\tsf=" + sf);
266         }
267         PrimitiveElement lid;
268         String JavaDoc lidname;
269         if (isInGenClass || sf == null || !isIdentifier) {
270             String JavaDoc prefix = mibh.getNameDefFieldPrefix(ref, isIdentifier, isInGenClass);
271             lidname = prefix + HIDDEN_LID_FIELD_NAME;
272         } else {
273             createField = false;
274             lidname = sf.name;
275         }
276         logger.log(BasicLevel.DEBUG, "lidname=" + lidname);
277         if (createField) {
278             lid = mibh.createNameDefField(mo, lidname, getFieldType());
279         } else {
280             lid = mibh.getPrimitiveField(mo, lidname);
281             if (lid == null) {
282                 throw new SpeedoException(
283                     mibh.getErrorMessage(tsc, mo, ref)
284                     + " Impossible to get the field '" + lidname + "'");
285             }
286         }
287         if ((isInGenClass && isIdentifier)
288             || (!isIdentifier && !isInGenClass && ref instanceof GenClassRef)) {
289             //Gen class identifier or gen class reference are based on basid
290
nd.setFieldName(lidname);
291         } else {
292             //class identifier or class reference are based on LongId
293
//fetch the composite name
294
CompositeName cn = manager.getCompositeName(LONG_ID_NAME());
295             if (cn == null) {
296                 cn = manager.createCompositeName(LONG_ID_NAME());
297                 ScalarField cnf = cn.createCompositeNameField(
298                     "lid", getFieldType(), PType.NOSIZE, PType.NOSIZE);
299                 cnf.setIsAutoCalculated(true);
300             }
301             //create the nameRef
302
NameRef nr = nd.createNameRef(cn);
303             nr.addProjection("lid", lid.getName());
304             if (isIdentifier) {
305                 assignDummyKeyToFamilly(ssc.jormclass, nd);
306                 if (ssc.jormclass.getSuperClasses().isEmpty()) {
307                     Expression expr = new Round(new DivideBy(
308                         new BasicParameterOperand(getFieldType(), "lid"),
309                         getBasicOperand()));
310                     try {
311                         expr.compileExpression();
312                     } catch (ExpressionException e) {
313                         throw new SpeedoException("Impossible to compile the filter of longid naming", e);
314                     }
315                     ssc.jormclass.setInheritanceFilter(nd, expr);
316                 }
317             }
318         }
319         if (mb != null && createField) {
320             mb.createNameDefMapping(hcm, nd, ssc, isIdentifier, isInGenClass);
321         }
322     }
323
324     private void assignDummyKeyToFamilly(org.objectweb.jorm.metainfo.api.Class clazz, NameDef nd) {
325         clazz.setInheritanceNamingKey(nd, "0");
326         for(Iterator JavaDoc it = clazz.getSubClasses().iterator(); it.hasNext();) {
327             assignDummyKeyToFamilly(((org.objectweb.jorm.metainfo.api.Class) it.next()), nd);
328         }
329     }
330
331     private SpeedoField fetchUniqueLongPKField(SpeedoClass tsc) throws SpeedoException {
332         Iterator JavaDoc it = tsc.jdoField.values().iterator();
333         SpeedoField sf = null;
334         ArrayList JavaDoc al = null;
335         while (it.hasNext()) {
336             SpeedoField _sf = (SpeedoField) it.next();
337             if (_sf.primaryKey) {
338                 if (sf != null) {
339                     if (al == null) {
340                         al = new ArrayList JavaDoc();
341                     }
342                     al.add(_sf.name);
343                 } else {
344                     sf = _sf;
345                 }
346             }
347         }
348         if (al != null) {
349             al.add(sf);
350             throw new SpeedoException(
351                 "Impossible to use an auto incremented identifier if " +
352                 "several fields have been marked as primary-key " + al
353                 + " in the class '" + tsc.getFQName() + "'.");
354         }
355         if (sf != null) {
356             String JavaDoc t = sf.type();
357             
358             if (!checkFieldType(t)) {
359                 throw new SpeedoException(
360                     "Impossible to use an auto incremented identifier: " +
361                     "the field type of '" + sf.name + "' is '" + sf.type()
362                     + "' and '" + getFieldType().getJavaName()
363                     + "' is expected (class '"
364                     + tsc.getFQName() + "'.");
365             }
366         }
367         return sf;
368     }
369
370     public void getJormNamingConfig(NameDef nd,
371                                     SpeedoClass targetClass,
372                                     MetaObject sourceMO,
373                                     String JavaDoc key,
374                                     Properties result) {
375
376         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
377         sb.append(LONG_ID_LID());
378         sb.append(NamingManagerHelper.HINTS_SEP);
379         boolean isGCR = sourceMO instanceof GenClassRef;
380         String JavaDoc binderInfo = (isGCR ? BINDER_FOR_GENCLASS : BINDER_FOR_CLASS);
381         sb.append(binderInfo);
382
383         SpeedoClass ancestor = targetClass.getAncestor();
384         String JavaDoc ancestorClassName;
385         String JavaDoc pncClassName;
386         if (!isGCR //For a Genclass ref or genclass identifier
387
&& (ancestor != null // has supper class
388
|| !targetClass.jormclass.getSubClasses().isEmpty()) // has sub class
389
) {
390             if (ancestor == null) {
391                 ancestor = targetClass;
392             }
393             ancestorClassName = ancestor.getFQName();
394             pncClassName = NamingRules.kfpncName(ancestorClassName);
395         } else {
396             ancestorClassName = targetClass.getFQName();
397             pncClassName = binderInfo;
398         }
399         //specify the pnc className
400
sb.append(NamingManagerHelper.HINTS_SEP);
401         sb.append(pncClassName);
402
403         //specify the className of the ancestor
404
sb.append(NamingManagerHelper.HINTS_SEP);
405         sb.append(ancestorClassName);
406         result.setProperty(key, sb.toString());
407     }
408
409     public PBinder getPBinder(String JavaDoc className,
410                               String JavaDoc hints,
411                               ClassLoader JavaDoc classLoader,
412                               byte mappingStructureRule,
413                               Map JavaDoc cn2binder,
414                               Map JavaDoc cn2pnc) throws PException {
415         init();
416         String JavaDoc binderInfo = NamingManagerHelper.getBinderClassNameFromHints(hints, LONG_ID_LID());
417         return getPBinder(className, binderInfo);
418     }
419
420     public PNamingContext getPNamingContext(String JavaDoc className,
421                                             String JavaDoc hints,
422                                             ClassLoader JavaDoc classLoader,
423                                             byte mappingStructureRule,
424                                             Map JavaDoc cn2binder,
425                                             Map JavaDoc cn2pnc,
426                                             Manager miManager,
427                                             PClassMapping pcm) throws PException {
428         init();
429         String JavaDoc[] tokens = NamingManagerHelper.getTokens(hints);
430         PNamingContext pnc = null;
431         if (tokens[NamingManagerHelper.BINDER_IDX].equals(tokens[NamingManagerHelper.PNC_IDX])) {
432             //The binder must be used as PNamingContext
433
pnc = (PNamingContext) cn2binder.get(className);
434             if (pnc == null) {
435                 //instanciate the binder/PNC
436
pnc = (PNamingContext) getPBinder(
437                     className, tokens[NamingManagerHelper.BINDER_IDX]);
438                 //register the binder/PNC as binder
439
cn2binder.put(className, pnc);
440             }
441             return pnc;
442         } else {
443             boolean register = false;
444             if (!tokens[NamingManagerHelper.PCLASS_IDX].equals(className)) {
445                 //The PNC of THE ancestor must be used
446
pnc = (PNamingContext) cn2pnc.get(tokens[NamingManagerHelper.PCLASS_IDX]);
447                 if (pnc == null) {
448                     register = true;
449                 }
450             }
451             if (pnc == null) {
452                 //instanciate the PNC
453
pnc = newClassPNamingContext();
454                 if (register) {
455                     cn2pnc.put(tokens[NamingManagerHelper.PCLASS_IDX], pnc);
456                 }
457             }
458         }
459         return pnc;
460     }
461
462     private PBinder getPBinder(String JavaDoc className, String JavaDoc binderInfo) throws PException {
463         if (binderInfo.startsWith(BINDER_FOR_GENCLASS)) {
464             return newGenClassPBinder();
465         } else if (binderInfo.startsWith(BINDER_FOR_CLASS)) {
466             return newClassPBinder(className, null);
467         } else {
468             throw new PException("Bad binder info: " + binderInfo);
469         }
470     }
471
472     public void setCache(CacheManager cache) {
473     }
474 }
475
Popular Tags