KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > mapper > lib > BasicJormFactory


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.mapper.lib;
19
20 import java.math.BigDecimal JavaDoc;
21 import java.math.BigInteger JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.Properties JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.regex.Pattern JavaDoc;
30
31 import javax.jdo.JDOException;
32 import javax.jdo.JDOFatalInternalException;
33 import javax.jdo.JDOUserException;
34 import javax.jdo.datastore.Sequence;
35 import javax.jdo.spi.JDOImplHelper;
36 import javax.jdo.spi.RegisterClassEvent;
37 import javax.jdo.spi.RegisterClassListener;
38
39 import org.objectweb.fractal.api.control.BindingController;
40 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
41 import org.objectweb.fractal.api.control.LifeCycleController;
42 import org.objectweb.jorm.api.PClassMapping;
43 import org.objectweb.jorm.api.PClassMappingCtrl;
44 import org.objectweb.jorm.api.PException;
45 import org.objectweb.jorm.api.PMapCluster;
46 import org.objectweb.jorm.api.PMapper;
47 import org.objectweb.jorm.lib.JormPathHelper;
48 import org.objectweb.jorm.mapper.rdb.genclass.RdbGenClassProp;
49 import org.objectweb.jorm.mapper.rdb.lib.RdbPrefetchablePCM;
50 import org.objectweb.jorm.metainfo.api.Package;
51 import org.objectweb.jorm.metainfo.lib.BasicClass;
52 import org.objectweb.jorm.metainfo.lib.BasicCompositeName;
53 import org.objectweb.jorm.metainfo.lib.JormManager;
54 import org.objectweb.jorm.naming.api.PBinder;
55 import org.objectweb.jorm.naming.api.PExceptionNaming;
56 import org.objectweb.jorm.naming.api.PName;
57 import org.objectweb.jorm.naming.api.PNameCoder;
58 import org.objectweb.jorm.naming.api.PNameManager;
59 import org.objectweb.jorm.naming.api.PNamingContext;
60 import org.objectweb.jorm.naming.lib.KFPNCManager;
61 import org.objectweb.jorm.type.api.PType;
62 import org.objectweb.perseus.cache.api.CacheManager;
63 import org.objectweb.perseus.persistence.api.ConnectionHolder;
64 import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager;
65 import org.objectweb.speedo.api.SpeedoProperties;
66 import org.objectweb.speedo.genclass.SpeedoGenClassHome;
67 import org.objectweb.speedo.generation.lib.NamingRules;
68 import org.objectweb.speedo.mapper.api.JormFactory;
69 import org.objectweb.speedo.mapper.api.JormFactoryAttributes;
70 import org.objectweb.speedo.mim.api.SpeedoHome;
71 import org.objectweb.speedo.naming.api.NamingManager;
72 import org.objectweb.speedo.naming.lib.NamingManagerFactory;
73 import org.objectweb.speedo.naming.lib.NamingManagerHelper;
74 import org.objectweb.speedo.pm.api.ProxyManagerFactory;
75 import org.objectweb.speedo.tools.StringReplace;
76 import org.objectweb.util.monolog.api.BasicLevel;
77 import org.objectweb.util.monolog.api.Logger;
78 import org.objectweb.util.monolog.api.LoggerFactory;
79
80 /**
81  * This class manages the initialization and the naming, of persistent class.
82  * The type of naming supported depends on the NamingManager registered into
83  * the NamingManagerFactory
84  *
85  * @see org.objectweb.speedo.naming.api.NamingManager
86  * @author S.Chassande-Barrioz
87  */

88 public class BasicJormFactory
89     implements JormFactory,
90     PNameCoder,
91     BindingController,
92     LifeCycleController,
93     JormFactoryAttributes,
94     RegisterClassListener {
95
96     /**
97      * fractal binding name to the mapper
98      */

99     public final static String JavaDoc MAPPER_BINDING = "mapper";
100     /**
101      * fractal binding name to the cache manager
102      */

103     public final static String JavaDoc CACHE_MANAGER_BINDING = "cache-manager";
104     public final static String JavaDoc TPM_BINDING = "transactional-persistence-manager";
105     public final static String JavaDoc PMF_BINDING = "proxy-manager-factory";
106
107     protected TransactionalPersistenceManager tpm;
108     
109     protected ProxyManagerFactory pmf;
110     
111     /**
112      * The mapper is used to map and find the Jorm classes.
113      */

114     protected PMapper mapper = null;
115
116     /**
117      * The cache to assign to the binders
118      */

119     protected CacheManager cache = null;
120
121     /**
122      * key = String class name
123      * value = PBinder binder of the class
124      */

125     protected Map JavaDoc binders = null;
126
127     /**
128      * key = String class name
129      * value = PNamingContext pnc of the class
130      */

131     protected Map JavaDoc pnamingContexts = null;
132     /**
133      * temporaly variable use in the recursive algorithm
134      */

135     protected Map JavaDoc cn2pcm = null;
136
137     /**
138      * The manager of NamingManager available.
139      */

140     private NamingManagerFactory nmf;
141
142     /**
143      * The rule concerning the data structure (jorm property of the mapper)
144      */

145     private byte mappingStructuresRule = JormFactoryAttributes.CREATE_IF_REQUIRED;
146
147     protected Logger logger = null;
148
149     private KFPNCManager kfpncManager;
150
151     private boolean mappingOnClassRegistration = false;
152     
153     private Properties JavaDoc speedoProperties;
154
155     /**
156      * builds the BasicJormFactory
157      * and the hosting structure for the binder list.
158      */

159     public BasicJormFactory() {
160         pnamingContexts = new HashMap JavaDoc();
161         binders = new HashMap JavaDoc();
162         cn2pcm = new HashMap JavaDoc();
163         nmf = new NamingManagerFactory();
164         kfpncManager = new KFPNCManager(pnamingContexts);
165     }
166
167     // IMPLEMENTATION OF THE JormFactoryAttributes INTERFACE //
168
//-------------------------------------------------------//
169

170     public byte getMappingStructureRule() {
171         return mappingStructuresRule;
172     }
173
174     public void setMappingStructureRule(byte rule) {
175         mappingStructuresRule = rule;
176     }
177
178     public boolean getMappingOnClassRegistration() {
179         return mappingOnClassRegistration;
180     }
181
182     public void setMappingOnClassRegistration(boolean val) {
183         mappingOnClassRegistration = val;
184     }
185
186     // IMPLEMENTATION OF THE UserBindingController INTERFACE //
187
//-------------------------------------------------------//
188

189     public String JavaDoc[] listFc() {
190         return new String JavaDoc[]{
191             MAPPER_BINDING,
192             CACHE_MANAGER_BINDING,
193             TPM_BINDING,
194             PMF_BINDING
195         };
196     }
197
198     public Object JavaDoc lookupFc(String JavaDoc s) {
199         if (MAPPER_BINDING.equals(s))
200             return mapper;
201         else if (CACHE_MANAGER_BINDING.equals(s))
202             return cache;
203         else if (TPM_BINDING.equals(s))
204             return tpm;
205         else if (PMF_BINDING.equals(s))
206             return pmf;
207         else
208             return null;
209     }
210
211     public void bindFc(String JavaDoc s, Object JavaDoc o) {
212         if ("logger".equals(s)) {
213             logger = (Logger) o;
214         } else if ("monolog-factory".equals(s)) {
215             nmf.setLogger(((LoggerFactory) o).getLogger(logger.getName() + ".naming-mmanager-factory"));
216             kfpncManager.setLogger(((LoggerFactory) o).getLogger(logger.getName() + ".kfpncmanager"));
217         } else if (MAPPER_BINDING.equals(s)) {
218             mapper = (PMapper) o;
219         } else if (CACHE_MANAGER_BINDING.equals(s)) {
220             cache = (CacheManager) o;
221         } else if (TPM_BINDING.equals(s)) {
222             tpm = (TransactionalPersistenceManager) o;
223         } else if (PMF_BINDING.equals(s)) {
224             pmf = (ProxyManagerFactory) o;
225         }
226     }
227
228     public void unbindFc(String JavaDoc s) {
229         if (MAPPER_BINDING.equals(s)) {
230             mapper = null;
231             nmf.setMapper(null);
232         } else if (CACHE_MANAGER_BINDING.equals(s)) {
233             cache = null;
234         } else if (TPM_BINDING.equals(s)) {
235             tpm = null;
236         } else if (PMF_BINDING.equals(s)) {
237             pmf = null;
238             nmf.setPmf(null);
239         }
240     }
241
242     private boolean started = false;
243
244     public String JavaDoc getFcState() {
245         return started ? STARTED : STOPPED;
246     }
247
248     public void startFc() throws IllegalLifeCycleException {
249         if (!started) {
250             mapper.addMapperEventListener(kfpncManager);
251             nmf.setMapper(mapper);
252             nmf.setCache(cache);
253             nmf.setPmf(pmf);
254             JDOImplHelper.getInstance().addRegisterClassListener(this);
255             started = true;
256         }
257     }
258
259     public void stopFc() throws IllegalLifeCycleException {
260         if (started) {
261             mapper.removeMapperEventListener(kfpncManager);
262             JDOImplHelper.getInstance().removeRegisterClassListener(this);
263             started = false;
264         }
265     }
266
267     // IMPLEMENTATION OF THE JormFactory INTERFACE //
268
//---------------------------------------------//
269

270     public PBinder getPBinder(Class JavaDoc clazz) throws PException {
271         String JavaDoc clName = clazz.getName();
272         PClassMapping pcm = mapper.lookup(clName);
273         if (pcm != null)
274             return pcm.getPBinder();
275         return getPClassMapping(clazz).getPBinder();
276     }
277
278     public PBinder getPBinder(String JavaDoc classname, ClassLoader JavaDoc cl) throws PException {
279         PClassMapping pcm = mapper.lookup(classname);
280         if (pcm != null)
281             return pcm.getPBinder();
282         return getPClassMapping(getClass(classname, cl)).getPBinder();
283     }
284
285     public ClassLoader JavaDoc getClassLoader(String JavaDoc className) {
286         Object JavaDoc o = mapper.lookup(className);
287         if (o == null) {
288             return null;
289         }
290         return getClassLoader(o.getClass());
291     }
292
293     public PClassMapping getGenClassMapping(String JavaDoc path) {
294         return JormPathHelper.getPClassMapping(path, mapper);
295     }
296
297     public PClassMapping getPClassMapping(Class JavaDoc clazz) throws PException {
298         PClassMapping pcm = mapper.lookup(clazz.getName());
299         if (pcm == null) {
300             pcm = getPClassMapping(clazz.getName(),
301                 clazz.getClassLoader());
302         }
303         return pcm;
304     }
305
306     /**
307      * This Method is a shortcut to the getPNamingContext(SpeedoProxy) method.
308      * It only does the instanciation of the classname
309      * (Class.ForName(classsName).newInstance()) and call the
310      * getPNamingContext(SpeedoProxy) method with the created instance. Then if
311      * an instance is availlable it is better to use the other method.
312      * @param classname the Jorm class name managed by the wanted PNamingContext
313      * @return the PNamingContext instance to use for the given jorm class name
314      * @throws org.objectweb.jorm.api.PException
315      */

316     public PNamingContext getPNamingContext(String JavaDoc classname, ClassLoader JavaDoc cl) throws PException {
317         return getPNamingContext(getClass(classname, cl));
318     }
319
320     public PNamingContext getPNamingContext(Class JavaDoc clazz) throws PException {
321         PClassMapping pcm = getPClassMapping(clazz);
322         String JavaDoc className = clazz.getName();
323         String JavaDoc path = JormPathHelper.getPath(className);
324         Properties JavaDoc classProperties = getClassProperties(clazz);
325         String JavaDoc jormConf = classProperties.getProperty(path);
326         if (jormConf != null) {
327             return (PNamingContext) findPNameManager(
328                 className, clazz.getClassLoader(), pcm, jormConf);
329         } else {
330             throw new PException(
331                 "Impossible to find the PNamingContext for the class "
332                 + className);
333         }
334     }
335
336     public Properties JavaDoc getSpeedoProperties() {
337         return speedoProperties;
338     }
339
340     HashMap JavaDoc pattern2prop;
341     public void setSpeedoProperties(Properties JavaDoc p) {
342         speedoProperties = p;
343         if (speedoProperties == null) {
344             return;
345         }
346         for(Iterator JavaDoc it=speedoProperties.keySet().iterator(); it.hasNext();) {
347             String JavaDoc key = (String JavaDoc) it.next();
348             if (key.indexOf('*') != -1 || key.indexOf('?') != -1) {
349                 //it is a pattern
350
if (logger != null) {
351                     logger.log(BasicLevel.DEBUG, "Pattern " + key);
352                 }
353                 Pattern JavaDoc pa = Pattern.compile(StringReplace.toJavaPattern(key));
354                 if (pattern2prop == null) {
355                     pattern2prop = new HashMap JavaDoc();
356                 }
357                 pattern2prop.put(pa, key);
358             }
359         }
360     }
361     
362     // IMPLEMENTATION OF THE RegisterClassListener INTERFACE //
363
//-------------------------------------------------------//
364

365     /**
366      * Automatic mechanism for persistent clas registration.
367      */

368     public void registerClass(RegisterClassEvent event) {
369         if (mappingOnClassRegistration) {
370             try {
371                 getPClassMapping(event.getRegisteredClass());
372             } catch (PException e) {
373                 throw new JDOException(
374                     "Impossible to initialize the persistent class '"
375                     + event.getRegisteredClass().getName() + "':", e);
376             }
377         }
378     }
379
380
381     // IMPLEMENTATION OF THE PNameCoder INTERFACE //
382
//--------------------------------------------//
383
public boolean codingSupported(int codingtype) {
384         return (codingtype & CTCOMPOSITE) != 0;
385     }
386
387     public PName decode(byte[] en) throws PExceptionNaming {
388         return null;
389     }
390
391     public PName decodeAbstract(Object JavaDoc oid, Object JavaDoc context)
392         throws PExceptionNaming, UnsupportedOperationException JavaDoc {
393         Class JavaDoc clazz = null;
394         ConnectionHolder conn = null;
395         if (context != null) {
396             if (!(context instanceof ConnectionHolder)) {
397                 clazz = (Class JavaDoc) context;
398             } else {
399                 conn = (ConnectionHolder) context;
400             }
401         }
402         if (oid instanceof PName) {
403             try {
404                 return ((PName) oid).resolve(conn);
405             } catch (PException e) {
406                 throw new JDOUserException("Impossible to decode the identifier "
407                     + oid + (clazz == null
408                     ? "" : " of the class " + clazz.getName()), e);
409             }
410         }
411         PBinder binder = null;
412         PName pn = null;
413         try {
414             if (clazz != null) {
415                 binder = getPBinder(clazz);
416             }
417             pn = nmf.decode(binder, oid, clazz, this);
418         } catch (PException e) {
419             throw new JDOUserException("Impossible to decode the identifier "
420                 + oid + (clazz == null
421                 ? "" : " of the class " + clazz.getName()), e);
422         }
423         if (pn != null) {
424             return pn;
425         }
426         if (binder != null) {
427             return binder.decodeAbstract(oid, null);
428         }
429         throw new JDOUserException("Impossible to decode the identifier "
430             + oid + (clazz == null
431             ? "" : " of the class " + clazz.getName()));
432     }
433
434     public PName decodeByte(byte en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
435         return decodeAbstract(new Byte JavaDoc(en), null);
436     }
437
438     public PName decodeObyte(Byte JavaDoc en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
439         return decodeAbstract(en, null);
440     }
441
442     public PName decodeChar(char en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
443         return decodeAbstract(new Character JavaDoc(en), null);
444     }
445
446     public PName decodeOchar(Character JavaDoc en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
447         return decodeAbstract(en, null);
448     }
449
450     public PName decodeInt(int en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
451         return decodeAbstract(new Integer JavaDoc(en), null);
452     }
453
454     public PName decodeOint(Integer JavaDoc en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
455         return decodeAbstract(en, null);
456     }
457
458     public PName decodeLong(long en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
459         return decodeAbstract(new Long JavaDoc(en), null);
460     }
461
462     public PName decodeOlong(Long JavaDoc en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
463         return decodeAbstract(en, null);
464     }
465
466     public PName decodeShort(short en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
467         return decodeAbstract(new Short JavaDoc(en), null);
468     }
469
470     public PName decodeOshort(Short JavaDoc en) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
471         return decodeAbstract(en, null);
472     }
473
474     public PName decodeString(String JavaDoc en) throws PExceptionNaming {
475         return decodeAbstract(en, null);
476     }
477
478     public PName decodeCharArray(char[] en) throws PExceptionNaming {
479         return decodeAbstract(en, null);
480     }
481
482     public PName decodeDate(Date JavaDoc en) throws PExceptionNaming {
483         return decodeAbstract(en, null);
484     }
485
486     public PName decodeBigInteger(BigInteger JavaDoc en) throws PExceptionNaming {
487         return decodeAbstract(en, null);
488     }
489
490     public PName decodeBigDecimal(BigDecimal JavaDoc en) throws PExceptionNaming {
491         return decodeAbstract(en, null);
492     }
493
494     public byte[] encode(PName pn) throws PExceptionNaming {
495         return pn.encode();
496     }
497
498     public Object JavaDoc encodeAbstract(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
499         try {
500             return nmf.encode(pn);
501         } catch (PException e) {
502             throw new JDOUserException(
503                 "Impossible to encode the identifier :" + pn);
504         }
505     }
506
507     public byte encodeByte(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
508         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a byte");
509     }
510
511     public Byte JavaDoc encodeObyte(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
512         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Byte");
513     }
514
515     public char encodeChar(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
516         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a char");
517     }
518
519     public Character JavaDoc encodeOchar(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
520         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Character");
521     }
522
523     public int encodeInt(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
524         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a int");
525     }
526
527     public Integer JavaDoc encodeOint(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
528         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Integer");
529     }
530
531     public long encodeLong(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
532         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a long");
533     }
534
535     public Long JavaDoc encodeOlong(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
536         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Long");
537     }
538
539     public short encodeShort(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
540         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a short");
541     }
542
543     public Short JavaDoc encodeOshort(PName pn) throws PExceptionNaming, UnsupportedOperationException JavaDoc {
544         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Short");
545     }
546
547     public String JavaDoc encodeString(PName pn) throws PExceptionNaming {
548         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a String");
549     }
550
551     public char[] encodeCharArray(PName pn) throws PExceptionNaming {
552         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a char[]");
553     }
554
555     public Date JavaDoc encodeDate(PName pn) throws PExceptionNaming {
556         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a Date");
557     }
558
559     public BigInteger JavaDoc encodeBigInteger(PName pn) throws PExceptionNaming {
560         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a BigInteger");
561     }
562
563     public BigDecimal JavaDoc encodeBigDecimal(PName pn) throws PExceptionNaming {
564         throw new UnsupportedOperationException JavaDoc("Impossible to encode to a BigDecimal");
565     }
566
567     public PName getNull() {
568         return null;
569     }
570
571     public void setNullPName(Object JavaDoc o) throws PException {
572     }
573
574     public boolean supportDynamicComposite() {
575         return false;
576     }
577
578     public boolean supportCompositeField(String JavaDoc fn, PType ft) {
579         return false;
580     }
581
582     public boolean supportStaticComposite() {
583         return false;
584     }
585
586     public PType getPType() {
587         return null;
588     }
589
590     public void setPType(PType pt) {
591     }
592
593     // PRIVATE METHODS //
594
//-----------------//
595

596
597     /**
598      * Fetch the configuration properties of a persistent class. The current
599      * speedo implementation make available the properties throught the static
600      * method jdoGetClassProperties() of the persistent class.
601      * The method implementation of this method invokes the static method.
602      * @param clazz is the java.lang.Class of a persistent class
603      * @return the java.util.Properties instance describing the configuration
604      * properties of the given persistent class.
605      * @throws PException if an error occurs during the method invocation.
606      */

607     private Properties JavaDoc getClassProperties(Class JavaDoc clazz) throws PException {
608         PClassMapping pcm = getPClassMapping(
609                 clazz.getName(), clazz.getClassLoader());
610         return ((SpeedoHome) pcm).getClassProperties();
611     }
612
613     /**
614      * This method is the real implementation of the getPClassMapping methods
615      * from the JormFactory interface. It instanciates and configure a
616      * persistent class. That represents
617      * - the instanciation of the PClassMapping
618      * - its configuration: fetching PNamingContext instances for each reference
619      * and allocating GenClassMapping for each gen class reference (collection).
620      * - the mapping of class (map operation on the mapper)
621      * - the management of data strucutre for the cluster (creation table)
622      *
623      * @param className is the class name of the persistent class which the
624      * PClasMapping is asked
625      * @param classLoader is the classloader for the persistent class. It
626      * assumes that the classloader contains the Speedo/Jorm classes about the
627      * persistent class (PClassMapping, PAccessor, PName, PBinder, PNG, ...)
628      * @return The PClassMapping of the persistent class
629      * @throws PException
630      */

631     public synchronized PClassMapping getPClassMapping(String JavaDoc className,
632                                                        ClassLoader JavaDoc classLoader)
633         throws PException {
634         boolean debug = logger.isLoggable(BasicLevel.DEBUG);
635         SpeedoHome pcm = (SpeedoHome) cn2pcm.get(className);
636         if (pcm != null) {
637             if (debug)
638                 logger.log(BasicLevel.DEBUG, "PClassMapping for class " + className
639                     + " is being configured:" + pcm);
640             return pcm;
641         }
642
643         pcm = (SpeedoHome) mapper.lookup(className);
644         if (pcm != null) {
645             if (debug)
646                 logger.log(BasicLevel.DEBUG, "PClassMapping for class " + className
647                     + " already exist:" + pcm);
648             return pcm;
649         }
650
651         // Creates the PClassMapping, its PBinder and the PNC
652
if (debug) {
653             logger.log(BasicLevel.DEBUG,
654                 "Looking for the PClassMapping of the class " + className);
655         }
656         String JavaDoc pcmcn = NamingRules.fqMappingName(className);
657         try {
658             pcm = (SpeedoHome) classLoader.loadClass(pcmcn).newInstance();
659         } catch (Exception JavaDoc e) {
660             throw new PException(e,
661                 "Impossible to instanciate the PClassMapping of the class "
662                 + className + ": " + pcmcn);
663         }
664         pcm.setTransactionalPersistenceManager(tpm);
665         pcm.setProxyManagerFactory(pmf);
666         Properties JavaDoc classProperties = pcm.getClassProperties();
667         if (debug) {
668             logger.log(BasicLevel.DEBUG, "Jorm config:" + classProperties);
669         }
670         //Load the Jorm Meta information
671
loadJormSpeedoMI(className, classProperties, classLoader);
672
673         // Fetch the Binder
674
PBinder binder = findPBinder(className, classLoader,
675             classProperties.getProperty(JormPathHelper.getPath(className)));
676         pcm.setPBinder(binder);
677         binder.setPClassMapping(pcm);
678
679         // Fetch the PNC of the class
680
PNameCoder classPnc = findPNameManager(
681             className, classLoader, pcm, classProperties.getProperty(JormPathHelper.getPath(className))
682         );
683         ((PClassMappingCtrl) pcm).setClassPNameCoder(classPnc);
684         //Configure references (PNameCoder and GenClassMappping)
685
RefConfig refConfig = new RefConfig(classProperties, classLoader);
686         cn2pcm.put(className, pcm);//register the pcm in order to avoid double configuration
687
pcm.configureRefFields(refConfig);
688         cn2pcm.remove(className);
689         if (debug) {
690             logger.log(BasicLevel.DEBUG, "PClassMapping/PBinder/PNC created for the class " + className);
691             logger.log(BasicLevel.DEBUG, "- pcm: " + pcm);
692             logger.log(BasicLevel.DEBUG, "- binder: " + binder);
693             logger.log(BasicLevel.DEBUG, "-pnc: " + classPnc);
694         }
695
696         applySpeedoProperties(pcm);
697         
698         <