KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > jorm > JormMIBuilder


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.generation.jorm;
19
20 import org.objectweb.speedo.metadata.SpeedoClass;
21 import org.objectweb.speedo.metadata.SpeedoField;
22 import org.objectweb.speedo.metadata.SpeedoIdentity;
23 import org.objectweb.speedo.metadata.SpeedoCollection;
24 import org.objectweb.speedo.metadata.SpeedoMap;
25 import org.objectweb.speedo.metadata.SpeedoExtension;
26 import org.objectweb.speedo.api.SpeedoException;
27 import org.objectweb.speedo.api.SpeedoProperties;
28 import org.objectweb.speedo.api.UserFieldMapping;
29 import org.objectweb.speedo.generation.generator.proxy.ProxyGenerator;
30 import org.objectweb.speedo.naming.api.MIBuilderHelper;
31 import org.objectweb.speedo.naming.lib.NamingManagerFactory;
32 import org.objectweb.jorm.metainfo.api.Class;
33 import org.objectweb.jorm.metainfo.api.Manager;
34 import org.objectweb.jorm.metainfo.api.ClassProject;
35 import org.objectweb.jorm.metainfo.api.Mapping;
36 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
37 import org.objectweb.jorm.metainfo.api.NameDef;
38 import org.objectweb.jorm.metainfo.api.ClassMapping;
39 import org.objectweb.jorm.metainfo.api.ClassRef;
40 import org.objectweb.jorm.metainfo.api.GenClassRef;
41 import org.objectweb.jorm.metainfo.api.GenClassMapping;
42 import org.objectweb.jorm.metainfo.api.MetaObject;
43 import org.objectweb.jorm.metainfo.api.ScalarField;
44 import org.objectweb.jorm.metainfo.api.CommonClassMapping;
45 import org.objectweb.jorm.metainfo.api.Reference;
46 import org.objectweb.jorm.metainfo.api.IdentifierMapping;
47 import org.objectweb.jorm.metainfo.api.TypedElement;
48 import org.objectweb.jorm.metainfo.api.ReferenceMapping;
49 import org.objectweb.jorm.metainfo.lib.MetaInfoPrinter;
50 import org.objectweb.jorm.type.api.PType;
51 import org.objectweb.jorm.type.api.PTypeSpace;
52 import org.objectweb.jorm.api.PException;
53 import org.objectweb.jorm.util.api.Loggable;
54 import org.objectweb.asm.Type;
55 import org.objectweb.util.monolog.api.Logger;
56 import org.objectweb.util.monolog.api.BasicLevel;
57
58 import java.util.Collection JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.List JavaDoc;
62
63 /**
64  * This class is a builder of jorm meta information. Its entries are the folowing:
65  * <UL>
66  * <LI>the jorm meta information manager,</LI>
67  * <LI>A collection of SpeedoClass object,</LI>
68  * <LI>the project name,</LI>
69  * <LI>the mapper name,</LI>
70  * <LI>a JormMIMappingBuilder instance able to build the mapping part for the
71  * mapper which the name is specified.</LI>
72  * </UL>
73  * @author S.Chassande-Barrioz
74  */

75 public class JormMIBuilder implements MIBuilderHelper {
76
77     /**
78      * is the prefix of the fields used to identify a generic class
79      */

80     public final static String JavaDoc GENCLASS_ID_PREFIX = "id_";
81
82     /**
83      * is the prefix of the fields used for the element of a generic class
84      */

85     public final static String JavaDoc GENCLASS_ELM_PREFIX = "elem_";
86
87     public final static String JavaDoc DEFAULT_RDB_BUILDER
88             = "org.objectweb.speedo.generation.jorm.rdb.OneTableRdbJormIMappingBuilder";
89
90     /**
91      * is the name of the index field in the list (Genclass).
92      */

93     public final static String JavaDoc LIST_INDEX = "idx";
94     public final static String JavaDoc MAP_INDEX = "idx";
95
96     /**
97      * is the jorm meta information manager iinside which the Class and the
98      * composite name must be defined.
99      */

100     private Manager manager = null;
101     private NamingManagerFactory nmf;
102
103     private Logger logger = null;
104     private boolean debug = false;
105
106     /**
107      * Builds a JormMIBuilder without a jorm meta information manager
108      * and a logger.
109      */

110     public JormMIBuilder() {
111     }
112
113     /**
114      * Builds a JormMIBuilder with a jorm meta information manager and a logger
115      * @param manager
116      */

117     public JormMIBuilder(Manager manager, Logger logger) {
118         this.manager = manager;
119         this.logger = logger;
120     }
121
122     /**
123      * Builds a JormMIBuilder with a jorm meta information manager and a logger
124      * @param manager
125      */

126     public JormMIBuilder(Manager manager, NamingManagerFactory nmf, Logger logger) {
127         this.manager = manager;
128         this.logger = logger;
129         this.nmf = nmf;
130     }
131
132     /**
133      * retrieves the jorm meta information manager hosting the Class and
134      * CompositeName instances.
135      */

136     public Manager getManager() {
137         return manager;
138     }
139
140     /**
141      * retrieves the jorm meta information manager hosting the Class and
142      * CompositeName instances.
143      */

144     public void setManager(Manager manager) {
145         this.manager = manager;
146     }
147
148     public Logger getLogger() {
149         return logger;
150     }
151
152     public void setLogger(Logger logger) {
153         this.logger = logger;
154     }
155
156     /**
157      * Creates the jorm meta information for a set of persistent classes. Only
158      * the generic part will be created.
159      *
160      * @param scs is a list of SpeedoClass instances.
161      * @return a Collection of jorm meta object composed by Class instances and
162      * CompositeName instances.
163      */

164     public Collection createMI(List JavaDoc scs) throws SpeedoException, PException {
165         return createMI(scs, null, null);
166     }
167
168     /**
169      * Creates the jorm meta information for a set of persistent classes.
170      * @param scs is a list of SpeedoClass instances.
171      * @param projectName is the project name for which the mapping must
172      * be defined. If the value is null no mapping will be generated.
173      * @param mapperName is the mapper name for which the mapping must
174      * be defined. If the value is null no mapping will be generated.
175      * @return a Collection of jorm meta object composed by Class instances and
176      * CompositeName instances.
177      */

178     public Collection createMI(List JavaDoc scs,
179                                String JavaDoc projectName,
180                                String JavaDoc mapperName)
181             throws SpeedoException, PException {
182         JormMIMappingBuilder jmimb = null;
183         String JavaDoc buildercn;
184         if (mapperName != null) {
185             if (mapperName.startsWith("rdb")) {
186                 buildercn = DEFAULT_RDB_BUILDER;
187             } else {
188                 throw new SpeedoException(
189                         "No default JormMIMappingBuilder for the mapper "
190                         + mapperName);
191             }
192             try {
193                 jmimb = (JormMIMappingBuilder)
194                         java.lang.Class.forName(buildercn).newInstance();
195             } catch (Exception JavaDoc e) {
196                 throw new SpeedoException("Impossible to instanciate a the class "
197                         + buildercn);
198             }
199             if (jmimb instanceof Loggable) {
200                 ((Loggable) jmimb).setLogger(logger);
201             }
202         }
203         return createMI(scs, projectName, mapperName, jmimb);
204     }
205     /**
206      * Creates the jorm meta information for a set of persistent classes.
207      * @param scs is a list of SpeedoClass instances.
208      * @param projectName is the project name for which the mapping must
209      * be defined
210      * @param mapperName is the mapper name for which the mapping must
211      * be defined
212      * @param mb is the build of the mapping part of the meta information
213      * @return a Collection of jorm meta object composed by Class instances and
214      * CompositeName instances.
215      */

216     public Collection createMI(List JavaDoc scs,
217                                String JavaDoc projectName,
218                                String JavaDoc mapperName,
219                                JormMIMappingBuilder mb)
220             throws SpeedoException, PException {
221         if (manager == null) {
222             throw new SpeedoException(
223                     "the Jorm meta information manager must be assigned");
224         }
225         int size = scs.size();
226         debug = logger.isLoggable(BasicLevel.DEBUG);
227         ArrayList JavaDoc createdMOs = new ArrayList JavaDoc(size * 2);
228         SpeedoClass sc;
229         String JavaDoc mn;
230         if (mapperName != null) {
231             // take the mapper name without the sub mapper name
232
int idx = mapperName.indexOf(".");
233             mn = (idx != -1 ? mapperName.substring(0, idx) : mapperName);
234         } else {
235             mn = null;
236         }
237
238         // Create Class meta objects
239
for(int i=0; i<size; i++) {
240             sc = (SpeedoClass) scs.get(i);
241             createJormClass(sc, projectName, mn, mb, createdMOs);
242         }
243
244         //Order the list in according to the inheritance order
245
List JavaDoc newscs = new ArrayList JavaDoc(size);
246         if (debug) {
247             logger.log(BasicLevel.DEBUG, "before ordering scs.size()=" + scs.size());
248         }
249         for(int i = 0; i<scs.size();) {
250             sc = (SpeedoClass) scs.get(i);
251             if (sc.superClassName == null) {
252                 //Add classes without parent
253
scs.remove(i);
254                 newscs.add(sc);
255                 if (debug) {
256                     logger.log(BasicLevel.DEBUG, "Class '" + sc.getFQName()
257                         + "' has no parent");
258                 }
259             } else {
260                 i++;
261             }
262         }
263         int idx = 0;
264         while (!scs.isEmpty() && idx < newscs.size()) {
265             //Take an element in the new list
266
sc = (SpeedoClass) newscs.get(idx);
267             if (debug) {
268                 logger.log(BasicLevel.DEBUG, "Find children of the class '" + sc.getFQName() + "'.");
269             }
270             //Search its children in the old list
271
for(int i = 0; i<scs.size();) {
272                 SpeedoClass child = (SpeedoClass) scs.get(i);
273                 if (child.jormclass.getSuperClass(sc.jormclass.getFQName()) != null) {
274                     //It is a child
275
scs.remove(i);
276                     newscs.add(child);
277                     if (debug) {
278                         logger.log(BasicLevel.DEBUG, "Class '"
279                             + child.getFQName() + "' is a child of the class '"
280                             + sc.getFQName() + "'.");
281                     }
282                 } else {
283                     i++;
284                 }
285             }
286             idx ++;
287         }
288         if (debug) {
289             logger.log(BasicLevel.DEBUG, "after ordering scs.size()=" + scs.size());
290             logger.log(BasicLevel.DEBUG, "newscs.size()=" + scs.size());
291         }
292         scs = newscs;
293
294         // Fill the meta information with primitive fields
295
for(int i=0; i<size; i++) {
296             sc = (SpeedoClass) scs.get(i);
297             createPrimitiveField(sc, projectName, mn, mb);
298         }
299         
300         //create parent class mapping and inheritance links
301
for(int i=0; i<size; i++) {
302             sc = (SpeedoClass) scs.get(i);
303             mb.finalizeClassMapping(sc,projectName, mn);
304         }
305         
306         // Define the identifier of classes (list with the inheritance order)
307
for(int i=0; i<size; i++) {
308             sc = (SpeedoClass) scs.get(i);
309             createIdentifierNameDef(sc, projectName, mn, mb, createdMOs);
310         }
311
312         // Fill the meta information with reference fields
313
for(int i=0; i<size; i++) {
314             sc = (SpeedoClass) scs.get(i);
315             createReferences(sc, projectName, mn, mb, createdMOs);
316         }
317
318         //define the mapping of inherited field (list with the inheritance order)
319
for(int i=0; i<size; i++) {
320             sc = (SpeedoClass) scs.get(i);
321             mapInheritance(sc, projectName, mn, mb);
322         }
323
324
325         if (logger.isLoggable(BasicLevel.DEBUG)) {
326             MetaInfoPrinter mip = new MetaInfoPrinter(manager);
327             for(int i=0; i<createdMOs.size(); i++) {
328                 mip.print("", (MetaObject) createdMOs.get(i), logger);
329             }
330         }
331         return createdMOs;
332     }
333
334     /**
335      * Creates the jorm meta information for a persistent class. Only the
336      * primitive fields are defined in the meta information. To define the
337      * references of a persistent object the 'createReferences' method must be
338      * used.
339      * @param sc is the Speedo meta object describing the class which the jorm
340      * meta information must be built.
341      * @param projectName is the project name for which the mapping must
342      * be defined
343      * @param mapperName is the mapper name for which the mapping must
344      * be defined
345      * @param mb is the build of the mapping part of the meta information
346      * @param createdMOs is a result paramter. This collection must be fill with
347      * the created Jorm Meta objects representing a class or a composite name.
348      * Here the meta object of the class will be added. In addition if the name
349      * def of the class is based on a composite name then its meta object will
350      * be added too.
351      */

352     private void createJormClass(SpeedoClass sc,
353                             String JavaDoc projectName,
354                             String JavaDoc mapperName,
355                             JormMIMappingBuilder mb,
356                             Collection createdMOs)
357             throws SpeedoException, PException {
358         Class JavaDoc clazz = manager.getClass(sc.getFQName());
359         if (clazz == null) {
360             clazz = manager.createClass(sc.getFQName());
361             createdMOs.add(clazz);
362         }
363         if (sc.superClassName != null) {
364             SpeedoClass parent = sc.getSpeedoClassFromContext(sc.superClassName);
365             if (parent == null) {
366                 throw new SpeedoException("No super class '"
367                         + sc.superClassName + "'found in the .jdo file: "
368                         + sc.getJDOFileName());
369             }
370             Class JavaDoc parentClazz = manager.getClass(parent.getFQName());
371             if (parentClazz == null) {
372                 parentClazz = manager.createClass(parent.getFQName());
373                 createdMOs.add(parentClazz);
374             }
375             clazz.addSuperClass(parentClazz);
376         }
377         sc.jormclass = clazz;
378         sc.jormclass.setAbstract(sc.isAbstract);
379         if (projectName != null && mapperName != null) {
380             ClassProject cp = clazz.getClassProject(projectName);
381             if (cp == null) {
382                 cp = clazz.createClassProject(projectName);
383             }
384             Mapping mapping = cp.getMapping(mapperName);
385             if (mapping != null) {
386                 //If the mapping is already defined then that means the jorm meta
387
// information has been already defined.
388
// => no meta object has been added.
389
return;
390             }
391             mapping = cp.createMapping(mapperName);
392             mb.createClassMapping(clazz, sc, mapping);
393         }
394     }
395
396     private void createPrimitiveField(SpeedoClass sc,
397                                       String JavaDoc projectName,
398                                       String JavaDoc mapperName,
399                             JormMIMappingBuilder mb)
400             throws SpeedoException, PException {
401         Class JavaDoc clazz = sc.jormclass;
402         ClassMapping cm = clazz.getClassProject(projectName)
403             .getMapping(mapperName).getClassMapping();
404         logger.log(BasicLevel.DEBUG, "Generate the Jorm MI for the class "
405                 + clazz.getFQName());
406         for (Iterator JavaDoc fieldsIt = sc.jdoField.values().iterator();fieldsIt.hasNext();) {
407             SpeedoField sp = (SpeedoField) fieldsIt.next();
408             SpeedoExtension se = sp.getExtensionByKey(
409                     SpeedoProperties.FIELD_CONVERTER);
410             PType ptype = null;
411             String JavaDoc className = null;
412             if (se != null) {
413                 try {
414                     UserFieldMapping ufm = (UserFieldMapping)
415                             java.lang.Class.forName(se.value).newInstance();
416                     ptype = getPrimitivePType(ufm.getStorageType().getName());
417                     if (ptype == null) {
418                         className = ufm.getStorageType().getName();
419                     }
420                 } catch (Exception JavaDoc e) {
421                     throw new SpeedoException(
422                             "Impossible to instanciate the UserFieldMapping class '"
423                             + se.value + "' for the field '" + sp.name
424                             + "' of the class '" + sc.getFQName() + "':", e);
425                 }
426             } else {
427                 Type type = Type.getType(sp.desc);
428                 ptype = getPrimitivePType(type);
429                 if (ptype == null) {
430                     className = type.getClassName();
431                 }
432             }
433             if (ptype == null) {
434                 if (isPersistentClass(className, sc.jdoPackage.name, manager)) {
435                     //reference field
436
continue;
437                 } else {
438                     logger.log(BasicLevel.INFO, "The field '" + sc.getFQName()
439                         + "." + sp.name + " is managed as a Serialized field.");
440                     ptype = PTypeSpace.SERIALIZED;
441                 }
442             }
443             logger.log(BasicLevel.DEBUG, "primitive field: " + sp.name + " / javatype: " + ptype.getJavaName());
444             se = sp.getExtensionByKey(SpeedoProperties.SIZE);
445             int size = PType.NOSIZE;
446             if (se != null) {
447                 try {
448                     size = Integer.parseInt(se.value);
449                 } catch (NumberFormatException JavaDoc e) {
450                     logger.log(BasicLevel.ERROR,
451                         "The specified size for the field '"
452                         + sp.name + "' of the class '" + sc.getFQName()
453                         + "' cannot be parsed: " + se.value, e);
454                 }
455             }
456             int scale = PType.NOSIZE;
457             se = sp.getExtensionByKey(SpeedoProperties.SCALE);
458             if (se != null) {
459                 try {
460                     scale = Integer.parseInt(se.value);
461                 } catch (NumberFormatException JavaDoc e) {
462                     logger.log(BasicLevel.ERROR,
463                         "The specified scale for the field '"
464                         + sp.name + "' of the class '" + sc.getFQName()
465                         + "' cannot be parsed: " + se.value, e);
466                 }
467             }
468             PrimitiveElement pe = clazz.createPrimitiveElement(
469                 sp.name, ptype, size, scale);
470             if (cm != null && mb != null) {
471                 mb.createFieldMapping(pe, sp, cm);
472             }
473         }
474     }
475
476     /**
477      * Creates the identifier name and its mapping for a persistent class.
478      * @param sc is the SpeedoClass meta object describing the persistent which
479      * the identifier has to be defined.
480      * @param projectName is the jorm project name
481      * @param mapperName is the mapper name
482      * @param mb is the builder of the Jorm Mapping meta info
483      * @param createdMOs is the list of created meta object (Class or
484      * CompositeName).
485      * @return a boolean value indicating if the identifier has been created. In
486      * the inheritance case the identifier is inherited from the parent. If the
487      * parent identifier is not defined, it is not possible to create the
488      * identifier of the specified persistent class.
489      */

490     private boolean createIdentifierNameDef(SpeedoClass sc,
491                                       String JavaDoc projectName,
492                                       String JavaDoc mapperName,
493                             JormMIMappingBuilder mb,
494                             Collection createdMOs)
495             throws SpeedoException, PException {
496         ClassMapping cm = sc.jormclass.getClassProject(projectName)
497             .getMapping(mapperName).getClassMapping();
498         NameDef classNd = null;
499         IdentifierMapping im = cm.getIdentifierMapping();
500         if (im != null) {
501             classNd = (NameDef) im.getLinkedMO();
502             if (classNd != null) {
503                 return true;
504             }
505         }
506         if (sc.superClassName == null) {
507             classNd = sc.jormclass.createNameDef();
508             fillNameDef(classNd, sc, sc, sc.jormclass, null, cm, mb, true, false,
509                 sc.identityType == SpeedoIdentity.CONTAINER_ID, createdMOs);
510             if (cm != null) {
511                 cm.createIdentifierMapping(classNd);
512             }
513         } else {
514             SpeedoClass parent = sc.getSpeedoClassFromContext(sc.superClassName);
515             im = parent.jormclass
516                 .getClassProject(projectName).getMapping(mapperName)
517                 .getClassMapping().getIdentifierMapping();
518             if (im != null) {
519                 classNd = (NameDef) im.getLinkedMO();
520                 if (classNd != null) {
521                     cm.createIdentifierMapping(classNd);
522                 }
523             }
524         }
525         if (debug) {
526             logger.log(BasicLevel.DEBUG, "Create the identifier of the class '"
527                 + sc.getFQName() + "'"
528                 + (sc.superClassName == null ? ""
529                 : "(parent class name='" + sc.superClassName + "')")
530                 + ", namedef=" + classNd + ".");
531         }
532         return classNd != null;
533     }
534
535     /**
536      * Builds the jorm meta objects representing the references of a persitent
537      * class. It is supposed that if the reference targets a persistent class,
538      * then the Class meta object and its NameDef are already defined.
539      * @param sc is the Speedo meta object describing the class which the jorm
540      * meta information must be built.
541      * @param projectName is the project name for which the mapping must
542      * be defined
543      * @param mapperName is the mapper name for which the mapping must
544      * be defined
545      * @param mb is the build of the mapping part of the meta information
546      * @param createdMOs is a result paramter. This collection must be fill with
547      * the created Jorm Meta objects representing a class or a composite name.
548      * Here only the new used composite name will be added.
549      */

550     private void createReferences(SpeedoClass sc,
551                                  String JavaDoc projectName,
552                                  String JavaDoc mapperName,
553                                  JormMIMappingBuilder mb,
554                                  Collection createdMOs)
555             throws SpeedoException, PException {
556         Class JavaDoc clazz = manager.getClass(sc.getFQName());
557         logger.log(BasicLevel.DEBUG, "Generate the Jorm MI for the references of class "
558                 + clazz.getFQName());
559         Mapping mapping = null;
560         ClassMapping cm = null;
561         if (projectName != null && mapperName != null) {
562             mapping = clazz.getClassProject(projectName)
563                 .getMapping(mapperName);
564             cm = mapping.getClassMapping();
565         }
566         Iterator JavaDoc fieldsIt = sc.jdoField.values().iterator();
567         //System.out.println("Manage reference of the class " + sc.getFQName());
568
while (fieldsIt.hasNext()) {
569             SpeedoField sp = (SpeedoField) fieldsIt.next();
570             if (clazz.getTypedElement(sp.name) != null) {
571                 //the primitive element is already managed before(createJormClass)
572
continue;
573             }
574             Type t = Type.getType(sp.desc);
575             String JavaDoc javatype = t.getClassName();
576             if (!isGenClassRef(javatype)) {
577                 // reference to a class //
578
//============================================================//
579
if (debug) {
580                     logger.log(BasicLevel.DEBUG, "Class reference field: "
581                         + sp.name + " / javatype: " + javatype);
582                 }
583                 // reference to a class
584
SpeedoClass tsc = sc.jdoPackage.jdoXMLDescriptor
585                         .getSpeedoClass(javatype, true);
586                 if (tsc == null) {
587                     throw new SpeedoException("No persistent class '"
588                             + javatype + "' found in the file: "
589                             + sc.jdoPackage.jdoXMLDescriptor.xmlFile);
590                 }
591                 Class JavaDoc tclass = manager.getClass(tsc.getFQName());
592                 if (tclass == null) {
593                     manager.createClass(tsc.getFQName());
594                 }
595                 ClassRef cr = clazz.createClassRef(sp.name, tclass);
596                 NameDef refNd = cr.createRefNameDef();
597                 fillNameDef(refNd, tsc, sc, clazz, cr, cm, mb, false, false, true, createdMOs);
598                 if ( cm != null) {
599                     cm.createReferenceMapping(sp.name, refNd);
600                     cm.addDependency(tsc.getFQName());
601                 }
602
603             } else {
604                 // reference to a generic class //
605
//============================================================//
606
String JavaDoc innerType = getInnerType(sp);
607                 if (innerType == null) {
608                     throw new SpeedoException("The inner element type is " +
609                             "required for the multivalued field '" + sp.name
610                             + "' of the class '" + sc.getFQName()
611                             + "' in the .jdo file '"
612                             + sc.jdoPackage.jdoXMLDescriptor.xmlFile + "'");
613                 }
614                 PType type = getPrimitivePType(innerType);
615                 if (type == null && !isPersistentClass(innerType, sc.jdoPackage.name, manager)) {
616                     logger.log(BasicLevel.INFO, "The field '" + sc.getFQName()
617                             + "." + sp.name + " is managed as a Serialized field.");
618                     type = PTypeSpace.SERIALIZED;
619                 }
620                 if (debug) {
621                     logger.log(BasicLevel.DEBUG, "GenClass reference field: "
622                         + sp.name + " / javatype: " + javatype
623                         + " / innerType: " + innerType
624                         + " / ptype=" + (type == null ? null : type.getJavaName()));
625                 }
626                 GenClassRef gcr = clazz.createGenClassRef(sp.name, javatype);
627                 GenClassMapping gcm = null;
628                 ClassRef cr = null;
629                 SpeedoClass tsc = null;
630
631                 //element of the gen class
632
if (type != null) {
633                     // gen class of primitive type
634
gcr.createPrimitiveElement(type, PType.NOSIZE, PType.NOSIZE);
635                 } else if (!isGenClassRef(innerType)) {
636                     // gen class of classref
637
tsc = sc.jdoPackage.jdoXMLDescriptor.smi
638                             .getSpeedoClass(innerType, sc.jdoPackage);
639                     if (tsc == null) {
640                         throw new SpeedoException("The persistent class '"
641                                 + sc.getFQName()
642                                 + "' tries to reference (througth the field '"
643                                 + sp.name
644                                 + "') the class '" + innerType
645                                 + "' not defined in the .jdo file '"
646                                 + sc.jdoPackage.jdoXMLDescriptor.xmlFile + "'");
647                     }
648                     Class JavaDoc tclass = manager.getClass(tsc.getFQName());
649                     if (tclass == null) {
650                         throw new SpeedoException("The inner element class '"
651                             + tsc.getFQName() + "' of the multivalued field '"
652                             + sp.name + "' of the class '" + sc.getFQName()
653                             + "' in the .jdo file '"
654                             + sc.jdoPackage.jdoXMLDescriptor.xmlFile
655                                 + "' has not been found among the persitent classes : "
656                             + manager.getClasses());
657                     }
658                     cr = gcr.createClassRef(tclass);
659                 } else {
660                     throw new SpeedoException(
661                             "unmanaged the inner-element of the field '"
662                             + sp.name + "' of the class '" + sc.getFQName()
663                             + "' : " + innerType);
664                 }
665                 //Map the element of the generic class
666
if (mapping != null) {
667                     gcm = mb.createGenClassMapping(gcr, sp, mapping);
668                     if (gcr.isPrimitive()) {
669                         mb.createFieldMapping(gcr.getPrimitiveElement(), null, gcm);
670                     } else {
671                         NameDef elemNd = cr.createRefNameDef();
672                         fillNameDef(elemNd, tsc, sc, gcr, gcr, gcm, mb, false, true, true, createdMOs);
673                         gcm.createReferenceMapping(sp.name, elemNd);
674                         cm.addDependency(tsc.getFQName());
675                     }
676                 }
677
678                 // reference to a generic class from the class
679
NameDef refNd = gcr.createRefNameDef();
680                 fillNameDef(refNd, sc, sc, clazz, gcr, cm, mb, false, false, false, createdMOs);
681                 if (cm !=