KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > xml2mi > lib > BasicDomParser


1 /**
2  * JORM: an implementation of a generic mapping system for persistent Java
3  * objects. Two mapping are supported: to RDBMS and to binary files.
4  * Copyright (C) 2001-2003 France Telecom R&D - INRIA
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * Contact: jorm-team@objectweb.org
21  *
22  */

23
24 package org.objectweb.jorm.xml2mi.lib;
25
26 import org.apache.tools.ant.types.DTDLocation;
27 import org.objectweb.jorm.api.PException;
28 import org.objectweb.jorm.metainfo.api.Class;
29 import org.objectweb.jorm.metainfo.api.Package;
30 import org.objectweb.jorm.metainfo.api.Manager;
31 import org.objectweb.jorm.metainfo.api.MetaObject;
32 import org.objectweb.jorm.metainfo.api.CompositeName;
33 import org.objectweb.jorm.metainfo.api.ClassProject;
34 import org.objectweb.jorm.metainfo.api.NameDef;
35 import org.objectweb.jorm.metainfo.api.ScalarField;
36 import org.objectweb.jorm.metainfo.api.GenClassRef;
37 import org.objectweb.jorm.metainfo.api.ClassRef;
38 import org.objectweb.jorm.metainfo.api.Reference;
39 import org.objectweb.jorm.metainfo.api.NameRef;
40 import org.objectweb.jorm.metainfo.api.Mapping;
41 import org.objectweb.jorm.metainfo.api.PrimitiveElement;
42 import org.objectweb.jorm.metainfo.api.TypedElement;
43 import org.objectweb.jorm.metainfo.api.ClassMapping;
44 import org.objectweb.jorm.metainfo.api.ParentClassMapping;
45 import org.objectweb.jorm.metainfo.api.IdentifierMapping;
46 import org.objectweb.jorm.type.api.PType;
47 import org.objectweb.jorm.type.api.PTypeSpace;
48 import org.objectweb.jorm.util.api.Loggable;
49 import org.objectweb.jorm.util.io.api.PathExplorer;
50 import org.objectweb.jorm.util.io.lib.DirJavaExplorer;
51 import org.objectweb.jorm.xml2mi.api.MappingParser;
52 import org.objectweb.jorm.xml2mi.api.Parser;
53 import org.objectweb.util.monolog.api.BasicLevel;
54 import org.objectweb.util.monolog.api.Logger;
55 import org.w3c.dom.Document JavaDoc;
56 import org.w3c.dom.Element JavaDoc;
57 import org.w3c.dom.Node JavaDoc;
58 import org.w3c.dom.NodeList JavaDoc;
59 import org.xml.sax.SAXException JavaDoc;
60
61 import java.io.InputStream JavaDoc;
62 import java.util.Map JavaDoc;
63 import java.util.HashMap JavaDoc;
64 import java.util.Hashtable JavaDoc;
65 import java.util.List JavaDoc;
66 import java.util.ArrayList JavaDoc;
67 import java.util.Collection JavaDoc;
68 import java.util.Iterator JavaDoc;
69 import java.util.Properties JavaDoc;
70 import java.util.Set JavaDoc;
71 import java.util.HashSet JavaDoc;
72
73 /**
74  * The BasicDomParser class implements the Parser interface.
75  * It uses the DOM trees associated to the XML files that are parsed in order
76  * to build the meta-objects.
77  * @author P. Dechamboux, X. Spengler
78  */

79 public class BasicDomParser
80     extends ParserHelper
81     implements Parser, Loggable {
82     /**
83      * The meta information manager for managing meta-objects within the
84      * context of a mapper.
85      */

86     private Manager metaInfoManager;
87
88     /**
89      * This hashmap associates a mapper name with a MappingParser object.
90      */

91     private Map JavaDoc mappingParsers = new HashMap JavaDoc();
92
93     /**
94      * A dom parser (here from xerses)
95      */

96     private SAXParserHelper parser;
97     /**
98      * pathExplorer is able to return input or output stream from a given file.
99      */

100     private PathExplorer pathExplorer;
101
102
103     /**
104      * the parser exception reached during the parsing of a file
105      */

106     private Exception JavaDoc parserException = null;
107
108
109     /**
110      * if the genDep flag is set to true, the dependance will be generated
111      */

112     private boolean genDep = false;
113
114     private DTDResolver resolver = null;
115
116     private List JavaDoc parsedMO = null;
117     private List JavaDoc undefinedMO = null;
118
119     /**
120      * A Map of String objects.
121      * key = a String object representing an id value.
122      * value = the associated GenClassRef object.
123      */

124     private Map JavaDoc idvalue2genclassref;
125
126     // IMPLEMENTATION OF METHODS FROM THE Parser INTERFACE
127

128     /**
129      * Main constructor for BasicDomParser. In order to compile XML files, it
130      * creates a DOMParser and initialzes it.
131      * @param dtdVerify true, the dtd must be used to validate xml files, else
132      * false
133      */

134     public void init(boolean dtdVerify, ArrayList JavaDoc dtds) {
135         Properties JavaDoc p = new Properties JavaDoc();
136         for (Iterator JavaDoc iter = dtds.iterator(); iter.hasNext();) {
137             DTDLocation element = (DTDLocation) iter.next();
138             p.setProperty(element.getPublicId(), element.getLocation());
139         }
140         try {
141             parser = new SAXParserHelper(p, logger, null, dtdVerify);
142         } catch (SAXException JavaDoc e) {
143             logger.log(BasicLevel.ERROR, "Error during the parser initialization", e);
144         }
145         parsedMO = new ArrayList JavaDoc();
146         undefinedMO = new ArrayList JavaDoc();
147         motable = new Hashtable JavaDoc();
148         mappingParsers = new HashMap JavaDoc();
149         idvalue2genclassref = new HashMap JavaDoc();
150     }
151
152     /**
153      * Adds a MappingParser object.
154      * @param mapperName a mapper name,
155      * mappingParser a MappingParser object.
156      */

157     public void addMappingParser(String JavaDoc mapperName,
158                                  MappingParser mappingParser) throws PException {
159         if (mappingParser == null) {
160             throw new PException("<" + mapperName +
161                                          "> MappingParser has not been created.");
162         }
163         if (getLogger().isLoggable(BasicLevel.DEBUG)) {
164             getLogger().log(BasicLevel.DEBUG,
165                             "Add a MappingParser (" + mapperName +
166                             ") for the current Parser");
167         }
168         if (!mappingParsers.containsKey(mapperName)) {
169             mappingParsers.put(mapperName, mappingParser);
170         }
171     }
172
173     /**
174      * Returns a MappingParser object.
175      * @param mapperName a mapper name,
176      * @return a MappingParser object.
177      */

178     public MappingParser getMappingParser(String JavaDoc mapperName) {
179         MappingParser mappingParser = (MappingParser) mappingParsers.get(mapperName);
180         return mappingParser;
181     }
182
183     /**
184      * Launches the parsing process. It reads and parses all the XML files
185      * and builds a schema of meta-objects for all of them.
186      * Before to use this method, the following object need to be set : Manager
187      * (with setMetaInfoManager), the PathExplorer (with setPathExplorer), the
188      * mapper name (with setMapperName), the mapping parser object (with setMappingParser).
189      *
190      * @param files an iterator over the name the XML files to be parsed
191      */

192     public Collection JavaDoc parse(Iterator JavaDoc files) throws PException {
193         Collection JavaDoc res = new ArrayList JavaDoc();
194         while (files.hasNext()) {
195             String JavaDoc filename = (String JavaDoc) files.next();
196             MetaObject mo = (MetaObject) motable.get(filename);
197             if (mo == null) {
198                 mo = parse(filename);
199                 if (mo != null) {
200                     motable.put(filename, mo);
201                 }
202             }
203             res.add(mo);
204         }
205         while (!undefinedMO.isEmpty()) {
206             MetaObject mo = (MetaObject) undefinedMO.remove(0);
207             String JavaDoc fqname = null;
208             if (mo instanceof Class JavaDoc) {
209                 fqname = ((Class JavaDoc) mo).getFQName();
210             } else if (mo instanceof CompositeName) {
211                 fqname = ((CompositeName) mo).getFQName();
212             } else {
213                 throw new PException("Unknown meta object: " + mo);
214             }
215             fqname = fqname.replace('.', fileSeparator.charAt(0)) + ".pd";
216             parse(fqname);
217             motable.put(fqname, mo);
218         }
219
220         // add implicit mappings
221
Set JavaDoc handledImplicitMappings = new HashSet JavaDoc();
222         for (Iterator JavaDoc itMO = res.iterator(); itMO.hasNext();) {
223             MetaObject metaObject = (MetaObject) itMO.next();
224             if (metaObject instanceof Class JavaDoc) {
225                 Class JavaDoc clazz = (Class JavaDoc) metaObject;
226                 addImplicitMappings(clazz, handledImplicitMappings);
227             }
228         }
229         // add implicit dependencies (implicit mappings must have be added before)
230
for (Iterator JavaDoc itMO = res.iterator(); itMO.hasNext();) {
231             MetaObject metaObject = (MetaObject) itMO.next();
232             if (metaObject instanceof Class JavaDoc) {
233                 Class JavaDoc clazz = (Class JavaDoc) metaObject;
234                 addImplicitDependencies(clazz);
235             }
236         }
237
238
239         Set JavaDoc filenames = motable.keySet();
240         if (! filenames.isEmpty()) {
241             for (Iterator JavaDoc iter = filenames.iterator(); iter.hasNext();) {
242                 String JavaDoc filename = (String JavaDoc) iter.next();
243                             logger.log(BasicLevel.DEBUG,
244                        "BasicDomParser filename in motable " + filename);
245                 //res.add(motable.get(filename));
246
}
247          }
248
249                             logger.log(BasicLevel.DEBUG,
250                        "BasicDomParser size of motable " + motable.size());
251
252                             logger.log(BasicLevel.DEBUG,
253                        "BasicDomParser size of res " + res.size());
254
255         return res;
256     }
257
258     /**
259      * Launches the parsing process.
260      * It reads and parses an XML file and builds a schema of meta-objects
261      * for it.
262      * Before to use this method, the following object need to be set : Manager
263      * (with setMetaInfoManager), the PathExplorer (with setPathExplorer), the
264      * mapper name (with setMapperName), the mapping parser object (with setMappingParser).
265      *
266      * @param file the name of the XML file to be parsed
267      */

268     public MetaObject parse(String JavaDoc file) throws PException {
269         logger.log(BasicLevel.INFO, "Parsing the file " + file + "...");
270         boolean debug = logger.isLoggable(BasicLevel.DEBUG);
271         if (debug)
272             logger.log(BasicLevel.DEBUG, "try to get input stream from <"
273                                          + file + ">");
274         InputStream JavaDoc is = pathExplorer.getInputStream(file);
275         if (is == null) {
276             throw new PException("The file '" + file +
277                                  "' has not been found in the following classpath \""
278                                  + pathExplorer.getClassPath() + "\"");
279         } else if (debug)
280             logger.log(BasicLevel.DEBUG, "File " + file + " found");
281         Document JavaDoc doc;
282         try {
283             doc = parser.parse(is);
284         } catch (Exception JavaDoc e) {
285             parserException = e;
286             throw new PException(e, "there is a problem (exception) during the parsing of <"
287                        + file + "> from the SAX module (SAXNotRecognized)");
288         }
289         if (debug)
290             logger.log(BasicLevel.DEBUG, "Parsing done.");
291         // Build the meta-information
292
return (doc.getDocumentElement() != null
293                 ? build(doc, file)
294                 : null);
295     }
296
297     /**
298      * Assigns a meta-information manager to a parser in order from it to
299      * create the meta-information related to the XML files it parses.
300      *
301      * @param mim the meta-information Manager to be associated to this parser
302      */

303     public void setMetaInfoManager(Manager mim) {
304         this.metaInfoManager = mim;
305     }
306
307     /**
308      * Assigns a PathExplorer object for locating files that have to be parsed.
309      *
310      * @param pathexpl the PathExplorer to be used for file location
311      */

312     public void setPathExplorer(PathExplorer pathexpl) {
313         pathExplorer = pathexpl;
314         if (pathExplorer == null) {
315             pathExplorer = new DirJavaExplorer();
316         }
317         logger.log(BasicLevel.DEBUG, "jorm classpath=" + pathExplorer.getClassPath());
318     }
319
320     /**
321      * Enables or disables the generation of the dependances.
322      *
323      * @param gendep true, the dependances are generated, else false
324      */

325     public void setGenDep(boolean gendep) {
326         genDep = gendep;
327     }
328
329     /**
330      * Allows to know if the dependances must be generated or not.
331      *
332      * @return true, if the dependances are generated, else false
333      */

334     public boolean isGenDep() {
335         return genDep;
336     }
337
338     /**
339      * returns the exception which is reached during the parsing of a file
340      *
341      * @return an Exception object
342      */

343     public Exception JavaDoc getParserException() {
344         return parserException;
345     }
346
347     ///////////////////////////////////////////////////////////////////
348
// local methods
349
///////////////////////////////////////////////////////////////////
350

351     /**
352      * builds the meta-information into the meta information manager.
353      * @param doc the document to read and move into meta information
354      * @param name the name of the document (file name).
355      *
356      * <!ELEMENT jorm (package?, ((class, mapping*) | composite-name)) >
357      */

358     private MetaObject build(Document JavaDoc doc, String JavaDoc name) throws PException {
359         if (logger.isLoggable(BasicLevel.DEBUG))
360             logger.log(BasicLevel.DEBUG,
361                        "build the meta information for <" + name + "> description file");
362         Package JavaDoc schema = null;
363         Class JavaDoc clazz = null;
364         CompositeName aname = null;
365         NodeList JavaDoc nodes = doc.getDocumentElement().getChildNodes();
366         for (int i = 0; i < nodes.getLength(); i++) {
367             Node JavaDoc node = nodes.item(i);
368             String JavaDoc nodeName = node.getNodeName();
369             if (nodeName.equals("package")) {
370                 if (logger.isLoggable(BasicLevel.DEBUG)) {
371                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
372                     logger.log(BasicLevel.DEBUG, "package name =<" +
373                                                  node.getFirstChild().getNodeValue() + ">");
374                 }
375                 schema = metaInfoManager.createPackage(node.getFirstChild().getNodeValue());
376                 if (logger.isLoggable(BasicLevel.DEBUG))
377                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
378             } else if (nodeName.equals("class")) {
379                 String JavaDoc className = ((Element) node).getAttribute("name");
380                 // compare the name of the file with the name of the class
381
int index = name.lastIndexOf(fileSeparator);
382                 int endIdx = name.lastIndexOf(".");
383                 if (endIdx <= index)
384                     endIdx = name.length();
385                 String JavaDoc sub = name.substring(index + 1, endIdx);
386                 if (!sub.equals(className))
387                     logger.log(BasicLevel.WARN, "Be careful, the name of the class" +
388                                                 " is different from the name of the file : " +
389                                                 sub + " and " + className +
390                                                 "(" + className + " is used)");
391
392                 if (logger.isLoggable(BasicLevel.DEBUG))
393                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
394
395                 String JavaDoc isAbstractString = ((Element) node).getAttribute("abstract").toLowerCase();
396                 if (schema == null) {
397                     schema = metaInfoManager.createPackage("");
398                 }
399                 clazz = schema.createClass(className);
400                 if (!parsedMO.contains(clazz)) {
401                     // The class has not been already loaded
402
parsedMO.add(clazz);
403                     undefinedMO.remove(clazz);
404                     //clazz.setAbstract(Boolean.getBoolean(isAbstractString));
405
boolean abstractClass = (isAbstractString != null && isAbstractString.equals("true"));
406                     clazz.setAbstract(abstractClass);
407                     if (logger.isLoggable(BasicLevel.DEBUG)) {
408                         logger.log(BasicLevel.DEBUG, "isAbstractString:<" + isAbstractString +">");
409                         // Boolean.getBoolean(): always returns false!
410
logger.log(BasicLevel.DEBUG, "Boolean.getBoolean(" + isAbstractString + "):" + Boolean.getBoolean(isAbstractString));
411                         logger.log(BasicLevel.DEBUG, "abstractClass:<" + abstractClass + ">");
412                         logger.log(BasicLevel.DEBUG, "class FQName:<" + clazz.getFQName() + "> isabstract:<" + clazz.isAbstract() +">");
413                     }
414                     processClass(clazz, (Element) node);
415                 }
416                 if (logger.isLoggable(BasicLevel.DEBUG))
417                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
418             } else if (nodeName.equals("mapping")) {
419                 if (logger.isLoggable(BasicLevel.DEBUG))
420                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
421                 String JavaDoc projectName = ((Element) node).getAttribute("project-name");
422                 if (clazz == null) {
423                     logger.log(BasicLevel.DEBUG, "the class definition is missing!");
424                     break;
425                 } else {
426                     if (logger.isLoggable(BasicLevel.DEBUG))
427                         logger.log(BasicLevel.DEBUG, "project-name =<" + projectName + ">");
428                     ClassProject classProject = clazz.createClassProject(projectName);
429                     parseMapping((Element) node, classProject);
430                 }
431                 if (logger.isLoggable(BasicLevel.DEBUG))
432                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
433             } else if (nodeName.equals("composite-name")) {
434                 String JavaDoc CN_name = ((Element) node).getAttribute("name");
435                 // compare the name of the file with the name of the class
436
int index = name.lastIndexOf(fileSeparator);
437                 String JavaDoc sub = name.substring(index + 1, name.length() - 3);
438
439                 if (sub.compareTo(CN_name) != 0)
440                     logger.log(BasicLevel.WARN, "Be careful, the name of the composite name" +
441                                                 " is different from the name of the file : " +
442                                                 name + " and " + CN_name +
443                                                 "(" + CN_name + " is used)");
444
445                 if (logger.isLoggable(BasicLevel.DEBUG))
446                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
447
448                 if (schema == null) {
449                     schema = metaInfoManager.createPackage("");
450                 }
451                 aname = schema.createCompositeName(CN_name);
452                 if (!parsedMO.contains(aname)) {
453                     parsedMO.add(aname);
454                     undefinedMO.remove(aname);
455                     // The composite name has not been already loaded
456
processCompositeName(aname, (Element) node);
457                 }
458                 if (logger.isLoggable(BasicLevel.DEBUG))
459                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
460                 return aname;
461             }
462         }
463         return clazz;
464     }
465
466     private void processCompositeName(CompositeName compositeName,
467                                       Element compositeNameElem) {
468
469         NodeList JavaDoc children = compositeNameElem.getChildNodes();
470         for (int i = 0; i < children.getLength(); i++) {
471             Node JavaDoc child = children.item(i);
472             String JavaDoc childName = child.getNodeName();
473
474             if (childName.equals("scalar-field")) {
475                 if (logger.isLoggable(BasicLevel.DEBUG))
476                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
477
478                 processScalarField(compositeName, (Element) child);
479
480                 if (logger.isLoggable(BasicLevel.DEBUG))
481                     logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
482             } else if (childName.equals("extension")) {
483                 // Get the compositename extension and add it to the list
484
// of inherited compositenames
485
if (logger.isLoggable(BasicLevel.DEBUG))
486                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
487
488                 String JavaDoc CN_name = ((Element) child).getAttribute("Name");
489                 CompositeName parentCN = metaInfoManager.getCompositeName(CN_name);
490                 if (parentCN == null) {
491                     parentCN = metaInfoManager.createCompositeName(CN_name);
492                     undefinedMO.add(parentCN);
493                 }
494                 compositeName.addInheritedCompositeName(parentCN);
495                 if (logger.isLoggable(BasicLevel.DEBUG))
496                     logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
497             }
498         }
499     }
500
501
502     /**
503      * Reads the subtree enrooted at class element and sets propreties of a
504      * Class object.
505      *
506      * <!ELEMENT class ((field | scalarfield)*, extension*, name-def*)>
507      * The Class object is created by the build() method.
508      *
509      * @param clazz an instance of Class,
510      * classElem a class element
511      */

512     private void processClass(Class JavaDoc clazz, Element classElem) throws PException {
513
514         NodeList JavaDoc children = classElem.getChildNodes();
515
516         for (int i = 0; i < children.getLength(); i++) {
517             Node JavaDoc child = children.item(i);
518             String JavaDoc nodeName = child.getNodeName();
519             if (nodeName.equals("field")) {
520                 if (logger.isLoggable(BasicLevel.DEBUG))
521                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
522                 processField(clazz, (Element) child);
523                 if (logger.isLoggable(BasicLevel.DEBUG))
524                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
525             } else if (nodeName.equals("scalar-field")) {
526                 if (logger.isLoggable(BasicLevel.DEBUG))
527                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
528                 processScalarField(clazz, (Element) child);
529                 if (logger.isLoggable(BasicLevel.DEBUG))
530                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
531             } else if (nodeName.equals("constant-value")) {
532                 if (logger.isLoggable(BasicLevel.DEBUG))
533                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
534                 processConstantValue(clazz, (Element) child);
535                 if (logger.isLoggable(BasicLevel.DEBUG))
536                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
537             } else if (nodeName.equals("extension")) {
538                 String JavaDoc fqcn = ((Element) child).getAttribute("name");
539                 if (logger.isLoggable(BasicLevel.DEBUG)) {
540                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
541                     //logger.log(BasicLevel.DEBUG, "name of the extension=<" +
542
// child.getFirstChild().getNodeValue() + ">");
543
logger.log(BasicLevel.DEBUG, "name of the extension=<" + fqcn + ">");
544                 }
545                 //String fqcn = child.getFirstChild().getNodeValue();
546
Class JavaDoc inheritedClass = metaInfoManager.getClass(fqcn);
547                 // First parse the inherited class
548
if (inheritedClass == null) {
549                     /*c = metaInfoManager.createClass(fqcn);
550                     undefinedMO.add(c);
551                     */

552                     fqcn = fqcn.replace('.', fileSeparator.charAt(0)) + ".pd";
553                     inheritedClass = (Class JavaDoc) parse(fqcn);
554                     motable.put(fqcn, inheritedClass);
555                 }
556                 clazz.addSuperClass(inheritedClass);
557                 if (logger.isLoggable(BasicLevel.DEBUG))
558                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
559             } else if (nodeName.equals("name-def")) {
560                 /* <!ATTLIST name-def
561                            id ID #REQUIRED
562                            name CDATA #IMPLIED>
563                  */

564                 if (logger.isLoggable(BasicLevel.DEBUG))
565                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
566                 NameDef nameDef = clazz.createNameDef();
567                 processNameDef(nameDef, ((Element) child));
568                 if (logger.isLoggable(BasicLevel.DEBUG))
569                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
570
571             } else if (nodeName.equals("name-def-filter")) {
572                 if (logger.isLoggable(BasicLevel.DEBUG))
573                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
574                 String JavaDoc filter = ((Element) child).getAttribute("filter");
575                 NameDef nd = getIdNameDef(clazz, ((Element) child).getAttribute("link-end"));
576                 clazz.setInheritanceFilter(nd, filter);
577                 if (logger.isLoggable(BasicLevel.DEBUG))
578                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
579
580             } else if (nodeName.equals("name-def-key")) {
581                 if (logger.isLoggable(BasicLevel.DEBUG))
582                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
583                 String JavaDoc key = ((Element) child).getAttribute("key");
584                 NameDef nd = getIdNameDef(clazz, ((Element) child).getAttribute("link-end"));
585                 clazz.setInheritanceNamingKey(nd, key);
586                 if (logger.isLoggable(BasicLevel.DEBUG))
587                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
588             }
589         }
590     }
591
592     /**
593      * Reads the subtree enrooted at scalar-field element and creates
594      * ScalarField objects.
595      *
596      * <!ELEMENT scalar-field (scalar-type, null-value?)>
597      *
598      * @param mo an instance of Class, or GenClassRef, or
599      * CompositeName
600      * @param scalarFieldElem a scalar-field element
601      */

602     private void processScalarField(MetaObject mo, Element scalarFieldElem) {
603         /* <!ATTLIST scalar-field
604                            name CDATA #REQUIRED>
605          */

606         String JavaDoc scalarFieldName = scalarFieldElem.getAttribute("name");
607         NodeList JavaDoc children = scalarFieldElem.getChildNodes();
608         ScalarField scalarField = null;
609         for (int j = 0; j < children.getLength(); j++) {
610             Node JavaDoc child = children.item(j);
611             String JavaDoc childName = child.getNodeName();
612             if (logger.isLoggable(BasicLevel.DEBUG))
613                 logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
614             if (childName.equals("scalar-type")) {
615                 String JavaDoc type = ((Element) child).getAttribute("type");
616                 if (mo instanceof Class JavaDoc) {
617                     scalarField = ((Class JavaDoc) mo).createHiddenField(
618                             scalarFieldName, getPType(type),
619                             Integer.parseInt(((Element) child).getAttribute("size")),
620                             Integer.parseInt(((Element) child).getAttribute("scale")));
621                 } else if (mo instanceof GenClassRef) {
622                     scalarField = ((GenClassRef) mo).createHiddenField(
623                             scalarFieldName, getPType(type),
624                             Integer.parseInt(((Element) child).getAttribute("size")),
625                         Integer.parseInt(((Element) child).getAttribute("scale")));
626                 } else if (mo instanceof CompositeName) {
627                     scalarField = ((CompositeName) mo).createCompositeNameField(
628                             scalarFieldName, getPType(type),
629                             Integer.parseInt(((Element) child).getAttribute("size")),
630                         Integer.parseInt(((Element) child).getAttribute("scale")));
631                 }
632             } else if (childName.equals("null-value")) {
633                 String JavaDoc value = ((Element) child).getAttribute("value");
634                 scalarField.setNullValue(value);
635             }
636             if (logger.isLoggable(BasicLevel.DEBUG))
637                 logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
638         }
639         scalarField.setIsAutoCalculated(Boolean.valueOf(
640             scalarFieldElem.getAttribute("auto-calculated")).booleanValue());
641         String JavaDoc status = scalarFieldElem.getAttribute("status");
642         if (status == null || status.equals("variable-persistent")) {
643             scalarField.setStatus(PrimitiveElement.VARIABLE_PERSISTENT);
644         } else if (status.equals("constant-persistent")) {
645             scalarField.setStatus(PrimitiveElement.CONSTANT_PERSISTENT);
646         } else if (status.equals("constant-non-persistent")) {
647             scalarField.setStatus(PrimitiveElement.CONSTANT_NON_PERSISTENT);
648         }
649     }
650
651     /**
652      * Reads the subtree enrooted at constant-value element and stores the
653      * constant value.
654      *
655      * <!ELEMENT constant-value EMPTY>
656      *
657      * @param mo an instance of Class
658      * @param constantElem a constant-value element
659      */

660     private void processConstantValue(MetaObject mo, Element constantElem)
661         throws PException {
662         /* <!ATTLIST scalar-field
663                            name CDATA #REQUIRED>
664         */

665         String JavaDoc fieldName = constantElem.getAttribute("field-name");
666         String JavaDoc fieldValue = constantElem.getAttribute("field-value");
667         TypedElement te = ((Class JavaDoc)mo).getTypedElement(fieldName);
668         if (te != null) {
669             if (!(te instanceof PrimitiveElement)) {
670                 throw new PException("Trying to assign a constant value to a non-primitive field " + fieldName);
671             }
672             PrimitiveElement pe = (PrimitiveElement) te;
673             if (! pe.isConstant()) {
674                 throw new PException("Trying to assign a constant value to a non-constant field " + fieldName);
675             }
676         }
677         if (logger.isLoggable(BasicLevel.DEBUG)) {
678             logger.log(BasicLevel.DEBUG, "Assign constant value: name="
679                     + fieldName + " / value=" + fieldValue);
680         }
681         ((Class JavaDoc)mo).setConstantValue(fieldName, fieldValue);
682     }
683
684     /**
685      * Reads the subtree enrooted at field element and adds a couple of
686      * field names in the NameRef object.
687      *
688      * <!ELEMENT field (primitive-type | (reference-type, field-ref?)) >
689      * The field-ref element is read in processFieldRef() that is called
690      * from processReferenceType().
691      *
692      * @param clazz an instance of Class,
693      * @param fieldElem a field element
694      */

695     private void processField(Class JavaDoc clazz, Element fieldElem) {
696         /* <!ATTLIST field
697                    name CDATA #REQUIRED>
698          */

699         String JavaDoc fieldName = fieldElem.getAttribute("name");
700         NodeList JavaDoc children = fieldElem.getChildNodes();
701         for (int i = 0; i < children.getLength(); i++) {
702             Node JavaDoc child = children.item(i);
703             String JavaDoc nodeName = child.getNodeName();
704             if (nodeName.equals("primitive-type")) {
705                 /* <!ATTLIST primitive-type
706                            id ID #REQUIRED
707                            type (...|...) #REQUIRED
708                            size CDATA #IMPLIED>
709                 */

710                 if (logger.isLoggable(BasicLevel.DEBUG))
711                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
712                 PrimitiveElement pe = clazz.createPrimitiveElement(fieldName,
713                     getPType(((Element) child).getAttribute("type")),
714                     Integer.parseInt(((Element) child).getAttribute("size")),
715                     Integer.parseInt(((Element) child).getAttribute("scale"))
716                 );
717                 pe.setIsAutoCalculated(Boolean.valueOf(
718                     ((Element) child).getAttribute("auto-calculated")).booleanValue());
719                 String JavaDoc status = fieldElem.getAttribute("status");
720                 if (status == null || status.equals("variable-persistent")) {
721                     pe.setStatus(PrimitiveElement.VARIABLE_PERSISTENT);
722                 } else if (status.equals("constant-persistent")) {
723                     pe.setStatus(PrimitiveElement.CONSTANT_PERSISTENT);
724                 } else if (status.equals("constant-non-persistent")) {
725                     pe.setStatus(PrimitiveElement.CONSTANT_NON_PERSISTENT);
726                 }
727                 if (logger.isLoggable(BasicLevel.DEBUG))
728                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
729             } else if (nodeName.equals("class-ref")) {
730                 if (logger.isLoggable(BasicLevel.DEBUG))
731                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
732                 processClassRef(clazz, (Element) child);
733                 if (logger.isLoggable(BasicLevel.DEBUG))
734                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
735             } else if (nodeName.equals("gen-class-ref")) {
736                 if (logger.isLoggable(BasicLevel.DEBUG))
737                     logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
738                 processGenClassRef(clazz, (Element) child);
739                 if (logger.isLoggable(BasicLevel.DEBUG))
740                     logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
741             }
742         }
743     }
744
745     /**
746      * Returns the referenced Class object.
747      * @param mo an instance of Class or GenClassRef,
748      * classRefElem a class-ref element.
749      * @return a Class object.
750      */

751     private Class JavaDoc getReferencedClass(MetaObject mo, Element classRefElem) {
752         String JavaDoc fqClassName = classRefElem.getAttribute("class-name");
753         Class JavaDoc aClass = metaInfoManager.getClass(fqClassName);
754         if (aClass == null) {
755             aClass = metaInfoManager.createClass(fqClassName);
756             undefinedMO.add(aClass);
757         }
758         return aClass;
759     }
760
761     /**
762      * Reads the subtree enrooted at classRefElem and creates a ClassRef object
763      * and one or several NameDef objects.
764      *
765      * <!ELEMENT class-ref (name-def+) >
766      * <!ATTLIST class-name CDATA #REQUIRED
767      shared (TRUE|FALSE) "TRUE">
768      *
769      * @param mo an instance of Class or GenClassRef,
770      * classRefElem a class-ref elemement.
771      */

772     private void processClassRef(MetaObject mo, Element classRefElem) {
773         Class JavaDoc referencedClass = getReferencedClass(mo, classRefElem);
774         // exception to raise if referencedClass == null !!!
775
ClassRef classRef = null;
776         if (mo instanceof Class JavaDoc) {
777             Node JavaDoc fieldNode = classRefElem.getParentNode();
778             String JavaDoc fieldName = ((Element) fieldNode).getAttribute("name");
779             classRef = ((Class JavaDoc) mo).createClassRef(fieldName, referencedClass);
780         } else if (mo instanceof GenClassRef) {
781             classRef = ((GenClassRef) mo).createClassRef(referencedClass);
782         }
783         NodeList JavaDoc children = classRefElem.getChildNodes();
784         for (int i = 0; i < children.getLength(); i++) {
785             Node JavaDoc child = children.item(i);
786             String JavaDoc childName = child.getNodeName();
787             if (childName.equals("name-def")) {
788                 /* <!ATTLIST name-def
789                            id ID #REQUIRED
790                            name CDATA #IMPLIED>
791                  */

792                 if (logger.isLoggable(BasicLevel.DEBUG))
793                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
794                 NameDef nameDef = classRef.createRefNameDef();
795                 processNameDef(nameDef, ((Element) child));
796                 if (logger.isLoggable(BasicLevel.DEBUG))
797                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
798             }
799         }
800     }
801
802     /**
803      * Reads the subtree enrooted at field-ref and adds in a Reference object
804      * a field name and its reverse field.
805      *
806      * @param mo an instance of Reference,
807      * refTypeElem a ref-type element
808      */

809     private void processFieldRef(Reference mo, Element refTypeElem) {
810         Node JavaDoc fieldRefNode = refTypeElem.getNextSibling();
811         if (fieldRefNode != null) {
812             /* <!ATTLIST field-ref
813                            field-name CDATA #REQUIRED
814              */

815             String JavaDoc fieldRefNodeName = fieldRefNode.getNodeName();
816             if (logger.isLoggable(BasicLevel.DEBUG))
817                 logger.log(BasicLevel.DEBUG,
818                            "begin =<" + fieldRefNodeName + ">");
819
820             // mo.addFieldRef( fieldName, fieldRefName);
821
if (logger.isLoggable(BasicLevel.DEBUG))
822                 logger.log(BasicLevel.DEBUG,
823                            "end =<" + fieldRefNodeName + ">");
824         }
825     }
826
827     /**
828      * returns the PType of a given name. If the type does not exist,
829      * null is returned.
830      * @param name the string representation of the name.
831      * @return the corresponding PType of its name.
832      */

833     private PType getPType(String JavaDoc name) {
834         if (name.equals(PTypeSpace.BOOLEAN.getJormName()))
835             return PTypeSpace.BOOLEAN;
836         if (name.equals(PTypeSpace.OBJBOOLEAN.getJormName()))
837             return PTypeSpace.OBJBOOLEAN;
838         else if (name.equals(PTypeSpace.OBJCHAR.getJormName())
839                 || name.equals("Character"))
840             return PTypeSpace.OBJCHAR;
841         else if (name.equals(PTypeSpace.CHAR.getJormName()))
842             return PTypeSpace.CHAR;
843         else if (name.equals(PTypeSpace.OBJBYTE.getJormName()))
844             return PTypeSpace.OBJBYTE;
845         else if (name.equals(PTypeSpace.BYTE.getJormName()))
846             return PTypeSpace.BYTE;
847         else if (name.equals(PTypeSpace.OBJSHORT.getJormName()))
848             return PTypeSpace.OBJSHORT;
849         else if (name.equals(PTypeSpace.SHORT.getJormName()))
850             return PTypeSpace.SHORT;
851         else if (name.equals(PTypeSpace.OBJINT.getJormName())
852                 || name.equals("Integer"))
853             return PTypeSpace.OBJINT;
854         else if (name.equals(PTypeSpace.INT.getJormName()))
855             return PTypeSpace.INT;
856         else if (name.equals(PTypeSpace.OBJLONG.getJormName()))
857             return PTypeSpace.OBJLONG;
858         else if (name.equals(PTypeSpace.LONG.getJormName()))
859             return PTypeSpace.LONG;
860         else if (name.equals(PTypeSpace.OBJFLOAT.getJormName()))
861             return PTypeSpace.OBJFLOAT;
862         else if (name.equals(PTypeSpace.FLOAT.getJormName()))
863             return PTypeSpace.FLOAT;
864         else if (name.equals(PTypeSpace.OBJDOUBLE.getJormName()))
865             return PTypeSpace.OBJDOUBLE;
866         else if (name.equals(PTypeSpace.DOUBLE.getJormName()))
867             return PTypeSpace.DOUBLE;
868         else if (name.equals(PTypeSpace.STRING.getJormName())
869                 || name.equals("String"))
870             return PTypeSpace.STRING;
871         else if (name.equals(PTypeSpace.DATE.getJormName())
872                 || name.equals("Date"))
873             return PTypeSpace.DATE;
874         else if (name.equals(PTypeSpace.SERIALIZED.getJormName())
875                 || name.equals("Serializable"))
876             return PTypeSpace.SERIALIZED;
877         else if (name.equals(PTypeSpace.BYTEARRAY.getJormName()))
878             return PTypeSpace.BYTEARRAY;
879         else if (name.equals(PTypeSpace.CHARARRAY.getJormName()))
880             return PTypeSpace.CHARARRAY;
881         else if (name.equals(PTypeSpace.BIGINTEGER.getJormName()))
882             return PTypeSpace.BIGINTEGER;
883         else if (name.equals(PTypeSpace.BIGDECIMAL.getJormName()))
884             return PTypeSpace.BIGDECIMAL;
885         else {
886             logger.log(BasicLevel.ERROR, "Invalid type name: " + name);
887             return null;
888         }
889     }
890
891
892     /**
893      * Reads the subtree enrooted at name-def element and:
894      * - sets system to true in the nameDef object, or
895      * - sets field name in the nameDef object, or
896      * - creates a NameRef object and possibly an hidden CompositeName object.
897      *
898      * <p> <!ELEMENT name-def (system | field-ref| composite-name-ref ) >
899      *
900      * @param nameDef an instance of NameDef,
901      * nameDefElem a name-def element
902      */

903     private void processNameDef(NameDef nameDef, Element nameDefElem) {
904         String JavaDoc name = nameDefElem.getAttribute("name");
905         nameDef.setName(name);
906         NodeList JavaDoc children = nameDefElem.getChildNodes();
907         for (int i = 0; i < children.getLength(); i++) {
908             Node JavaDoc child = children.item(i);
909             String JavaDoc childName = child.getNodeName();
910             if (childName.equals("system")) {
911                 if (logger.isLoggable(BasicLevel.DEBUG))
912                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
913                 nameDef.setSystem(true);
914                 if (logger.isLoggable(BasicLevel.DEBUG))
915                     logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
916             } else if (childName.equals("field-ref")) {
917                 /* <!ATTLIST field-ref
918                             field-name CDATA #REQUIRED>
919                  */

920                 if (logger.isLoggable(BasicLevel.DEBUG))
921                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
922                 String JavaDoc fieldName = ((Element) child).getAttribute("field-name");
923                 nameDef.setFieldName(fieldName);
924                 if (logger.isLoggable(BasicLevel.DEBUG))
925                     logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
926             } else if (childName.equals("composite-name-ref")) {
927                 /* <!ATTLIST composite-name-ref
928                             composite-name-name CDATA #REQUIRED>
929                  */

930                 if (logger.isLoggable(BasicLevel.DEBUG))
931                     logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
932                 String JavaDoc fqCN_Name =
933                         ((Element) child).getAttribute("composite-name-name");
934                 if (logger.isLoggable(BasicLevel.DEBUG)) {
935                     logger.log(BasicLevel.DEBUG,
936                                "composite-name-ref composite-name-name =<" + fqCN_Name + ">");
937                 }
938                 int lastindexofpoint = fqCN_Name.lastIndexOf('.');
939                 String JavaDoc CN_Name = null;
940                 Package JavaDoc CN_Schema = null;
941                 // search the schema of the referenced composite name
942
if (lastindexofpoint != -1) {
943                     // the name of the schema is specified
944
String JavaDoc schemaName =
945                             fqCN_Name.substring(0, fqCN_Name.lastIndexOf('.'));
946                     CN_Schema = metaInfoManager.createPackage(schemaName);
947                     CN_Name =
948                             fqCN_Name.substring(fqCN_Name.lastIndexOf('.') + 1,
949                                                 fqCN_Name.length());
950                 } else {
951                     // the name of the schema is not specified TJRS = 2 ?
952
Object JavaDoc tmp = nameDef.getParent();
953                     // get the schema
954
while (!(tmp instanceof Package JavaDoc)) {
955                         tmp = ((MetaObject) tmp).getParent();
956                     }
957                     CN_Schema = (Package JavaDoc) tmp;
958                     logger.log(BasicLevel.WARN, "Be careful, " +
959                                                 "the name of package (Package name) is not specified, " +
960                                                 "continue with " + CN_Schema.getName() + " schema.");
961                     CN_Name = fqCN_Name;
962                 }
963                 if (logger.isLoggable(BasicLevel.DEBUG)) {
964                     logger.log(BasicLevel.DEBUG,
965                                "schema name =<" + CN_Schema.getName() + ">");
966                 }
967                 // try to get the class from the schema
968
CompositeName aCompositeName = CN_Schema.getCompositeName(CN_Name);
969                 if (aCompositeName == null) {
970                     aCompositeName = CN_Schema.createCompositeName(CN_Name);
971                     undefinedMO.add(aCompositeName);
972                 }
973                 NameRef nameRef = nameDef.createNameRef(aCompositeName);
974                 processNameRef(nameRef, ((Element) child));
975                 if (logger.isLoggable(BasicLevel.DEBUG))
976                     logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
977             }
978         }
979     }
980
981     /**
982      * Reads the subtree enrooted at composite-name-ref and adds a couple of
983      * field names in the NameRef object.
984      *
985      * <p> <!ELEMENT composite-name-ref (composite-name-field-projection+) >
986      *
987      * @param nameRef an instance of NameRef,
988      * compositeNameRefElem a composite-name-ref element
989      */

990     private void processNameRef(NameRef nameRef, Element compositeNameRefElem) {
991         NodeList JavaDoc children = compositeNameRefElem.getChildNodes();
992         for (int i = 0; i < children.getLength(); i++) {
993             Node JavaDoc child = children.item(i);
994             String JavaDoc nodeName = child.getNodeName();
995             if (nodeName.equals("composite-name-field-projection")) {
996                 /* <!ATTLIST composite-name-field-projection
997                             composite-name-field-name CDATA #REQUIRED
998                             class-field-name CDATA #REQUIRED>
999                  */

1000                if (logger.isLoggable(BasicLevel.DEBUG))
1001                    logger.log(BasicLevel.DEBUG, "begin =<" + nodeName + ">");
1002                String JavaDoc CN_fieldName =
1003                        ((Element) child).getAttribute("composite-name-field-name");
1004                String JavaDoc classfieldName =
1005                        ((Element) child).getAttribute("class-field-name");
1006                nameRef.addProjection(CN_fieldName, classfieldName);
1007                if (logger.isLoggable(BasicLevel.DEBUG))
1008                    logger.log(BasicLevel.DEBUG, "end =<" + nodeName + ">");
1009            }
1010        }
1011    }
1012
1013    /**
1014     * Reads the subtree enrooted at index and adds a couple of
1015     * field names in the NameRef object.
1016     *
1017     * <p> <!ELEMENT index (field-ref+) >
1018     *
1019     * @param index an instance of Index,
1020     * indexElem an index element
1021     */

1022/*
1023    private void processIndex(Index index, Element indexElem) {
1024        NodeList children = indexElem.getChildNodes();
1025        for (int i = 0; i < children.getLength(); i++) {
1026            Node child = children.item(i);
1027            String childName = child.getNodeName();
1028            if (childName.equals("field-ref")) {
1029               // <!ATTLIST field-ref
1030               // field-name CDATA #REQUIRED>
1031
1032                if (logger.isLoggable(BasicLevel.DEBUG))
1033                    logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1034                String fieldName = ((Element) child).getAttribute("field-name");
1035                index.addFieldName(fieldName);
1036                if (logger.isLoggable(BasicLevel.DEBUG))
1037                    logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1038            }
1039        }
1040    }
1041*/

1042
1043    /**
1044     * Reads the subtree enrooted at gen-class-ref element and:
1045     * - parses a gen-class element
1046     *
1047     * <!ELEMENT gen-class-ref (gen-class, name-def+)>
1048     *
1049     * @param mo an instance of Class or GenClassRef,
1050     * genClassRefElem a gen-class-ref element.
1051     */

1052    private void processGenClassRef(MetaObject mo, Element genClassRefElem) {
1053        NodeList JavaDoc children = genClassRefElem.getChildNodes();
1054        GenClassRef genClassRef = null;
1055        for (int i = 0; i < children.getLength(); i++) {
1056            Node JavaDoc child = children.item(i);
1057            String JavaDoc childName = child.getNodeName();
1058            if (childName.equals("gen-class")) {
1059                /* <!ATTLIST gen-class
1060                           id ID #REQUIRED
1061                           gen-class-name CDATA #REQUIRED>
1062                 */

1063                if (logger.isLoggable(BasicLevel.DEBUG))
1064                    logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1065                String JavaDoc genClassName =
1066                        ((Element) child).getAttribute("gen-class-name");
1067                if (mo instanceof Class JavaDoc) {
1068                    Node JavaDoc fieldNode = genClassRefElem.getParentNode();
1069                    String JavaDoc fieldName = ((Element) fieldNode).getAttribute("name");
1070                    genClassRef =
1071                            ((Class JavaDoc) mo).createGenClassRef(fieldName, genClassName);
1072                    /* idvalue2genclassref.put(fieldName, genClassRef);
1073                    if (logger.isLoggable(BasicLevel.DEBUG)) {
1074                        logger.log(BasicLevel.DEBUG, "mo=class, gen class id =<" + fieldName + ">");
1075                    }
1076                    */

1077                } else if (mo instanceof GenClassRef) {
1078                    genClassRef =
1079                            ((GenClassRef) mo).createGenClassRef(genClassName);
1080                }
1081                idvalue2genclassref.put(genClassRef.getGenClassId(), genClassRef);
1082                if (logger.isLoggable(BasicLevel.DEBUG)) {
1083                    logger.log(BasicLevel.DEBUG,
1084                               "genclass id =<" + genClassRef.getGenClassId() + ">");
1085                }
1086                processGenClass(genClassRef, (Element) child);
1087                if (logger.isLoggable(BasicLevel.DEBUG))
1088                    logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1089            } else if (childName.equals("name-def")) {
1090                /* <!ATTLIST name-def
1091                           id ID #REQUIRED
1092                           name CDATA #IMPLIED>
1093                 */

1094                if (logger.isLoggable(BasicLevel.DEBUG))
1095                    logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1096                NameDef nameDef = genClassRef.createRefNameDef();
1097                processNameDef(nameDef, ((Element) child));
1098                if (logger.isLoggable(BasicLevel.DEBUG))
1099                    logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1100            }
1101        }
1102    }
1103
1104    /**
1105     * Reads the subtree enrooted at gen-class element and:
1106     * - parses scalar-field element(s),
1107     * - creates NameDef object(s),
1108     * - creates an Index object,
1109     * - creates a PrimitiveType object,
1110     * - parses a reference-type element
1111     *
1112     * <!ELEMENT gen-class
1113     * (scalarfield*, name-def+, index?, (primitive-type | reference-type)>
1114     *
1115     * @param genClassRef an instance of GenClassRef,
1116     * genClassElem a gen-class element
1117     */

1118    private void processGenClass(GenClassRef genClassRef,
1119                                 Element genClassElem) {
1120        NodeList JavaDoc children = genClassElem.getChildNodes();
1121        for (int i = 0; i < children.getLength(); i++) {
1122            Node JavaDoc child = children.item(i);
1123            String JavaDoc childName = child.getNodeName();
1124            if (logger.isLoggable(BasicLevel.DEBUG))
1125                logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1126            if (childName.equals("scalar-field")) {
1127                /* <!ATTLIST scalar-field
1128                           name CDATA #REQUIRED>
1129                 */

1130                processScalarField(genClassRef, (Element) child);
1131            } else if (childName.equals("name-def")) {
1132                /* <!ATTLIST name-def
1133                           id ID #REQUIRED
1134                           name CDATA #IMPLIED>
1135                 */

1136                NameDef nameDef = genClassRef.createIdNameDef();
1137                processNameDef(nameDef, ((Element) child));
1138            } else if (childName.equals("index")) {
1139                processIndex(genClassRef, ((Element) child));
1140            } else if (childName.equals("primitive-type")) {
1141                /* <!ATTLIST primitive-type
1142                           id ID #REQUIRED
1143                           type (...|...) #REQUIRED
1144                           size CDATA #IMPLIED>
1145                */

1146                genClassRef.createPrimitiveElement(
1147                        getPType(((Element) child).getAttribute("type")),
1148                        Integer.parseInt(((Element) child).getAttribute("size")),
1149                    Integer.parseInt(((Element) child).getAttribute("scale")));
1150            } else if (childName.equals("class-ref")) {
1151                processClassRef(genClassRef, (Element) child);
1152            } else if (childName.equals("gen-class-ref")) {
1153                processClassRef(genClassRef, (Element) child);
1154            }
1155            if (logger.isLoggable(BasicLevel.DEBUG))
1156                logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1157        }
1158    }
1159
1160    private void processIndex(GenClassRef genClassRef,
1161                              Element indexElem) {
1162        NodeList JavaDoc children = indexElem.getChildNodes();
1163        for (int i = 0; i < children.getLength(); i++) {
1164            Node JavaDoc child = children.item(i);
1165            String JavaDoc childName = child.getNodeName();
1166            if (logger.isLoggable(BasicLevel.DEBUG))
1167                logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1168            if (childName.equals("field-ref")) {
1169                genClassRef.addIndexField(
1170                        ((Element) child).getAttribute("field-name"));
1171            }
1172            if (logger.isLoggable(BasicLevel.DEBUG))
1173                logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1174        }
1175    }
1176
1177    /**
1178     * Parses the mapping part of the XML file and builds the corresponding
1179     * meta-information for a given Class object.
1180     * Manager, PathExplorer, MapperName and MappingName must be set before the
1181     * call of this method.
1182     *
1183     * @param mappingElem the node to treat
1184     */

1185    public void parseMapping(Element mappingElem, ClassProject classProject)
1186            throws PException {
1187        NodeList JavaDoc nodes = mappingElem.getChildNodes();
1188        MappingParser mp = null;
1189        Mapping mapping = null;
1190        String JavaDoc mapperName = null;
1191        for (int i = 0; i < nodes.getLength(); i++) {
1192            Node JavaDoc child = nodes.item(i);
1193            String JavaDoc childName = child.getNodeName();
1194            if (logger.isLoggable(BasicLevel.DEBUG)) {
1195                logger.log(BasicLevel.DEBUG, "begin =<" + childName + ">");
1196            }
1197            int pos = childName.indexOf("-");
1198            if (pos == -1) {
1199                continue;
1200            }
1201            mapperName = childName.substring(0, pos);
1202            mp = getMappingParser(mapperName);
1203            if (mp == null) {
1204                if (logger.isLoggable(BasicLevel.DEBUG)) {
1205                    logger.log(BasicLevel.DEBUG,
1206                               "cannot get the mapping parser!");
1207                }
1208                break;
1209            }
1210            mp.setPathExplorer(pathExplorer);
1211            ((Loggable) mp).setLogger(logger);
1212            mp.setMetaInfoManager(metaInfoManager);
1213            mp.setidvalue2genclassref(idvalue2genclassref);
1214            mp.setCurrentClass((Class JavaDoc) classProject.getParent());
1215            mp.setmotable(motable);
1216            mapping = classProject.createMapping(mapperName);
1217            if (logger.isLoggable(BasicLevel.DEBUG)) {
1218                logger.log(BasicLevel.DEBUG,
1219                           "current class =<" + ((Class JavaDoc) classProject.getParent()).getName() + ">");
1220                logger.log(BasicLevel.DEBUG,
1221                           "current project =<" + classProject.getProjectName() + ">");
1222                logger.log(BasicLevel.DEBUG,
1223                           "current mapping =<" + mapping.getMapperName() + ">");
1224            }
1225            if (mapping instanceof Loggable) {
1226                if (loggerFactory != null) {
1227                    ((Loggable) mapping).setLoggerFactory(loggerFactory);
1228                } else if (logger != null) {
1229                    ((Loggable) mapping).setLogger(logger);
1230                }
1231            }
1232            mp.parseMapping((Element) child, mapping);
1233            if (logger.isLoggable(BasicLevel.DEBUG)) {
1234                logger.log(BasicLevel.DEBUG, "end =<" + childName + ">");
1235            }
1236        }
1237    }
1238
1239    /**
1240     * Defines a logger object.
1241     *
1242     * @param logger the logger object
1243     */

1244    public void setLogger(Logger logger) {
1245        this.logger = logger;
1246        if (resolver != null)
1247            resolver.setLogger(logger);
1248    }
1249
1250    /**
1251     * Add implicit mappings. For each super class of class clazz, and for each class project
1252     * defined for this super class and for each mapping defined in this class project
1253     * look if there is a defined parent class mapping defined, and if not, create one
1254     * with an implicit rule.
1255     * Also add implicit id-mappings if not exists
1256     * TODO: this should be implemented as a visitor in a chain of visitors to which
1257     * the meta-info tree is given to be completed, enhanced, verified, decorated, etc
1258     * @param clazz the class to which add implicit mappings
1259     */

1260    private void addImplicitMappings(Class JavaDoc clazz, Set JavaDoc handledClasses) {
1261        // loop on super classes
1262
for (Iterator JavaDoc itSuperClass = clazz.getSuperClasses().iterator();
1263             itSuperClass.hasNext();) {
1264            Class JavaDoc superClass = (Class JavaDoc) itSuperClass.next();
1265            // implicit mappings of super class must have been added
1266
if (!handledClasses.contains(superClass)) {
1267                addImplicitMappings(superClass, handledClasses);
1268            }
1269            // loop on class project of super class
1270
for (Iterator JavaDoc itProject = superClass.getClassProjects().iterator();
1271                 itProject.hasNext();) {
1272                ClassProject superClassProject = (ClassProject) itProject.next();
1273                // create a corresponding class project in current class if it
1274
// does not exist
1275
ClassProject classProject = clazz.
1276                        getClassProject(superClassProject.getProjectName());
1277                if (classProject == null) {
1278                    classProject = clazz.createClassProject(superClassProject.
1279                            getProjectName());
1280                    logger.log(BasicLevel.DEBUG, "Create implicit class project "
1281                            + clazz.getName() + "<" + classProject.getProjectName()
1282                            + ">");
1283                }
1284
1285                // loop on mappings of super class
1286
for (Iterator JavaDoc itMapping = superClassProject.getMappings().iterator();
1287                     itMapping.hasNext();) {
1288                    Mapping superMapping = (Mapping) itMapping.next();
1289                    // create corresponding mapping, classmapping, id mapping
1290
// & parent class mapping in current class if they do not exist
1291
Mapping mapping = classProject.getMapping(superMapping.getMapperName());
1292                    ClassMapping classMapping;
1293                    if (mapping == null) {
1294                        mapping = classProject.createMapping(superMapping.getMapperName());
1295                        classMapping = mapping.createClassMapping("");
1296                        logger.log(BasicLevel.DEBUG, "Create implicit mapping & class mapping "
1297                                + clazz.getName() + "<" + classMapping.getProjectName() +
1298                                "," + classMapping.getMapperName() + ">");
1299                    } else {
1300                        classMapping = mapping.getClassMapping();
1301                    }
1302                    IdentifierMapping id = classMapping.getIdentifierMapping();
1303                    if (id == null) {
1304                        logger.log(BasicLevel.DEBUG, "Create implicit id mapping "
1305                                + clazz.getName() + "<" + classMapping.getProjectName() +
1306                                "," + classMapping.getMapperName() + "> from IM of "
1307                                + superClass.getName());
1308                        classMapping.createIdentifierMapping((NameDef)
1309                                superMapping.getClassMapping().getIdentifierMapping().getLinkedMO());
1310                    }
1311                    ParentClassMapping pm = classMapping.getParentClassMapping(superClass.getFQName());
1312                    if (pm == null) {
1313                        pm = classMapping.createImplicitParentClassMapping(superClass);
1314                        logger.log(BasicLevel.DEBUG, "Create implicit parent class mapping "
1315                                + clazz.getName() + "<" + classMapping.getProjectName() +
1316                                "," + classMapping.getMapperName() + "> to "
1317                                + superClass.getName());
1318                    }
1319                }
1320            }
1321        }
1322    }
1323    /**
1324     * Add implicit dependencies.
1325     * TODO: this should be implemented as a visitor in a chain of visitors to which
1326     * the meta-info tree is given to be completed, enhanced, verified, decorated, etc
1327     * @param clazz the class to which add implicit mappings
1328     */

1329    private void addImplicitDependencies(Class JavaDoc clazz) {
1330            for (Iterator JavaDoc itProject = clazz.getClassProjects().iterator(); itProject.hasNext();) {
1331                ClassProject classProject = (ClassProject) itProject.next();
1332                for (Iterator JavaDoc itMapping = classProject.getMappings().iterator(); itMapping.hasNext();) {
1333                    Mapping mapping = (Mapping) itMapping.next();
1334                    ClassMapping classMapping = mapping.getClassMapping();
1335                    classMapping.addImplicitDependencies();
1336                }
1337            }
1338        }
1339
1340}
1341
1342
Popular Tags