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