Package org.objectweb.speedo.generation.parser.jdo

Source Code of org.objectweb.speedo.generation.parser.jdo.JDO2Parser

/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Contact: speedo@objectweb.org
* Authors: S.Chassande-Barrioz.
*
*/

package org.objectweb.speedo.generation.parser.jdo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.generation.api.SpeedoXMLError;
import org.objectweb.speedo.generation.parser.AbstractParser;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoCollection;
import org.objectweb.speedo.metadata.SpeedoColumn;
import org.objectweb.speedo.metadata.SpeedoCommonField;
import org.objectweb.speedo.metadata.SpeedoDiscriminator;
import org.objectweb.speedo.metadata.SpeedoElement;
import org.objectweb.speedo.metadata.SpeedoExtension;
import org.objectweb.speedo.metadata.SpeedoFetchGroup;
import org.objectweb.speedo.metadata.SpeedoField;
import org.objectweb.speedo.metadata.SpeedoIdentity;
import org.objectweb.speedo.metadata.SpeedoIndex;
import org.objectweb.speedo.metadata.SpeedoInheritance;
import org.objectweb.speedo.metadata.SpeedoInheritedField;
import org.objectweb.speedo.metadata.SpeedoJoin;
import org.objectweb.speedo.metadata.SpeedoJoinColumn;
import org.objectweb.speedo.metadata.SpeedoMap;
import org.objectweb.speedo.metadata.SpeedoNoFieldColumn;
import org.objectweb.speedo.metadata.SpeedoNullValue;
import org.objectweb.speedo.metadata.SpeedoPackage;
import org.objectweb.speedo.metadata.SpeedoPredefinedQuery;
import org.objectweb.speedo.metadata.SpeedoTable;
import org.objectweb.speedo.metadata.SpeedoVersion;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.speedo.sequence.jdo.JDOSequence;
import org.objectweb.speedo.sequence.lib.SpeedoSequence;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* This class is a parser of the JDO2 persistent descriptor. It includes the
* parsing the O/R mapping.
*
* @author S.Chassande-Barrioz
*/
public class JDO2Parser extends AbstractParser {
 
  public JDO2Parser() {
    super(Personality.JDO);
  }
 
  public void process() throws SpeedoException {
    super.process();
    //compute fields number for each class
    for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) {   
          SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();   
          for (Iterator itPack = desc.packages.values().iterator(); itPack.hasNext();) {   
              SpeedoPackage sp = (SpeedoPackage) itPack.next();   
              for (Iterator itclass = sp.classes.values().iterator(); itclass.hasNext();) {   
                  SpeedoClass clazz = (SpeedoClass) itclass.next();   
                  clazz.computeFieldNumbers();   
              }   
          }   
      }
  }
 
  protected String getLoggerName() {
    return "jdo2";
  }
 
    protected Object treatDocument(Node node, Object mo) throws SpeedoException {
        SpeedoXMLDescriptor xmlDesc = (SpeedoXMLDescriptor) mo;
        Map docChildren = groupChildrenByName(node);
        List l = (List) docChildren.remove("jdo");
        if (l != null) {
          for (int i = 0; i < l.size(); i++) {
              treatJdoNode((Node) l.get(i), xmlDesc);
          }
        }
        return mo;
    }
    protected Object treatJdoNode(Node jdoNode, SpeedoXMLDescriptor xmlDesc) throws SpeedoException {
        Map jdoChildren = groupChildrenByName(jdoNode);
        List packages = (List) jdoChildren.remove("package");
        if (packages != null) {
          for (int i = 0; i < packages.size(); i++) {
              Node packageNode = (Node) packages.get(i);
              Node n = packageNode.getAttributes().getNamedItem("name");
              if (n == null) {
                  logger.log(BasicLevel.ERROR, "Attribute 'name' for tag package required.");
                  continue;
              }
              SpeedoPackage p = new SpeedoPackage();
              p.name = n.getNodeValue();
              xmlDesc.add(p, true, logger);
              logger.log(BasicLevel.DEBUG, "Parsing package: name= " + p.name);
              Map packageChildren = groupChildrenByName(packageNode);
              treatExtensions((List) packageChildren.remove("extension"), p);
              List l = (List) packageChildren.remove("sequence");
              if (l != null) {
                for (int j = 0; j < l.size(); j++) {
                    Node classNode = (Node) l.get(j);
                    treatSequenceNode(classNode, p);
                }
              }
              l = (List) packageChildren.remove("class");
              if (l != null) {
                  for (int j = 0; j < l.size(); j++) {
                      Node classNode = (Node) l.get(j);
                      treatClassNode(classNode, p);
                  }
              }
          }
        }
        List queries = (List) jdoChildren.remove("query");
        if (queries != null) {
            xmlDesc.queries = new ArrayList(queries.size());
          for (int i = 0; i < queries.size(); i++) {
              SpeedoPredefinedQuery spq = getQuery((Node) queries.get(i));
              xmlDesc.queries.add(spq);
          }
        }
        return xmlDesc;
    }
    private Map groupChildrenByName(Node n) {
        NodeList nl = n.getChildNodes();
        int size = nl.getLength();
        if (size == 0) {
            return Collections.EMPTY_MAP;
        }
        HashMap result = new HashMap(size);
        for (int i = 0; i < size; i++) {
            Node child = nl.item(i);
            String name = child.getNodeName();
            List l = (List) result.get(name);
            if (l == null) {
                l = new ArrayList();
                result.put(name, l);
            }
            l.add(child);
        }
        return result;
    }
    private void unmanaged(Node node, Map unmanagedChildren) {
        if (unmanagedChildren!= null && unmanagedChildren.size() > 0) {
            logger.log(BasicLevel.WARN, "Umanaged sub node of "
                    + node.getNodeName() + ": " + unmanagedChildren.keySet());
        }
    }
    private void treatSequenceNode(Node seqNode, SpeedoPackage p) throws SpeedoException {
        SpeedoSequence s = new JDOSequence();
        Node n = null;
       
        //<!ATTLIST sequence name CDATA #REQUIRED>
        n = seqNode.getAttributes().getNamedItem("name");
        if (n == null)
            throw new SpeedoXMLError("Attribute name for tag sequence requested.");
        s.name = n.getNodeValue();
        p.addSequence(s);

        //<!ATTLIST sequence datastore-sequence CDATA #IMPLIED>
        n = seqNode.getAttributes().getNamedItem("datastore-sequence");
        if (n != null)
            s.datastoreName = n.getNodeValue();
         
        //<!ATTLIST sequence factory-class CDATA #IMPLIED>
        n = seqNode.getAttributes().getNamedItem("factory-class");
        if (n != null) {
            s.factoryClass = n.getNodeValue();
        }

        //<!ATTLIST sequence strategy (nontransactional|contiguous|noncontiguous) #REQUIRED>
        n = seqNode.getAttributes().getNamedItem("strategy");
        if (n == null) {
            throw new SpeedoXMLError("Attribute strategy for tag sequence requested.");
        }
        s.strategy = SpeedoSequence.strategyToByte(n.getNodeValue());
       
        //<!ELEMENT sequence (extension*)>
        Map seqChildren = groupChildrenByName(seqNode);
        treatExtensions((List) seqChildren.get("extension"), p);

        if (debug) {
            logger.log(BasicLevel.DEBUG, "New sequence: "
                + "name=" + s.name
                + "  / datastoreName = " + s.datastoreName
                + "  / factoryClass = " + s.factoryClass
                + "  / strategy = " + s.strategy
            );
        }
    }   
    private void treatIndexNode(Node indexNode, SpeedoClass sc) throws SpeedoException {
      SpeedoIndex si = new SpeedoIndex();
    Node n = null;

        //attribut name (compulsory)
        n = indexNode.getAttributes().getNamedItem("name");
        if (n == null)
            throw new SpeedoXMLError("Attribute name for tag index requested.");
        si.name = n.getNodeValue();
       
        //attribute unique
        n = indexNode.getAttributes().getNamedItem("unique");
        if (n != null)
             si.unique = Boolean.valueOf(n.getNodeValue()).booleanValue();

        //attribute table (compulsory)
        n = indexNode.getAttributes().getNamedItem("table");
        if (n == null)
            throw new SpeedoXMLError("Attribute table for tag index requested.");
        si.table = n.getNodeValue();
       
        //add the SpeedoIndex to the SpeedoTable
        boolean linked = false;
        //test the main table
        if (sc.mainTable != null) {
          if (sc.mainTable.name.equals(si.table)) {
            sc.mainTable.indexes.add(si);
            linked = true;
          }
        }
        //and if no success with the main table try the joined tables
        if (!linked && sc.joinToExtTables != null) {
          for (int i = 0; i < sc.joinToExtTables.length && !linked; i++) {
            if (sc.joinToExtTables[i].extTable.name.equals(si.name)) {
              sc.joinToExtTables[i].extTable.indexes.add(si);
              linked = true;
            }
          }
        }
       
        Map classChildren = groupChildrenByName(indexNode);
        //extension*, (column|field|property)*
        treatExtensions((List) classChildren.get("extension"), si);
        List l = (List) classChildren.get("field");
        if (l != null) {
          for (int j = 0; j < l.size(); j++) {
                treatFieldNode((Node) l.get(j), sc, si);
            }
        }
        si.speedoClass = sc;
        //      TODO: unmanaged stuff of class
        unmanaged(null, new String[]{"column", "property"}, indexNode, classChildren);
    }
   
    private void treatClassNode(Node classNode, SpeedoPackage p) throws SpeedoException {
        Node n = null;
        //attribute name (compulsory)
        n = classNode.getAttributes().getNamedItem("name");
        if (n == null) {
            logger.log(BasicLevel.ERROR, "Attribute 'name' for tag class required.");
            return;
        }
        SpeedoClass c = new SpeedoClass();
        c.name = n.getNodeValue();
        p.addClass(c, true, logger);

        //attribute identity-type
        n = classNode.getAttributes().getNamedItem("identity-type");
        if (n != null)
            c.setIdentityType(SpeedoIdentity.getStrategy(n.getNodeValue()));
         
        //attribute object-id
        n = classNode.getAttributes().getNamedItem("objectid-class");
        if (n != null) {
            c.identity.objectidClass = n.getNodeValue();
            c.setIdentityType(SpeedoIdentity.USER_ID);
        }

        //attribute requires-extent is not taken into account

        //attribute detachable
        n = classNode.getAttributes().getNamedItem("detachable");
        if (n != null)
            c.isDetachable = Boolean.valueOf(n.getNodeValue()).booleanValue();
             
        //attribute persistence-capable-superclass
        n = classNode.getAttributes().getNamedItem("persistence-capable-superclass");
        if (n != null) {
            if (c.inheritance == null) {
                c.inheritance = new SpeedoInheritance(c);
            }
            c.inheritance.superClassName = n.getNodeValue();
        }
        //attribute table
        n = classNode.getAttributes().getNamedItem("table");
        if (n != null) {
            c.mainTable = new SpeedoTable();
            c.mainTable.name = n.getNodeValue();
        }
        if (c.mainTable == null) {
            if (c.inheritance == null
                    || c.inheritance.strategy == SpeedoInheritance.STRATEGY_NEW_TABLE) {
                c.mainTable = new SpeedoTable();
                c.mainTable.name = c.name.toUpperCase();
            }
        }

        logger.log(BasicLevel.DEBUG, "New class: "
                + "name=" + c.name
                + "  / id = " + c.getIdentityType()
                + "  / idClass = " + c.identity.objectidClass
                + "  / detachable = " + c.isDetachable
        );
       
        Map classChildren = groupChildrenByName(classNode);
        //extension*, implements*, datastore-identity?, inheritance?, version?,
        // join*, foreign-key*, index*, unique*, field*, query*, fetch-group*, extension*
        treatExtensions((List) classChildren.get("extension"), c);
        List l = (List) classChildren.get("datastore-identity");
        if (l != null) {
            treatDataStoreId((Node) l.get(0), c);
        }
        l = (List) classChildren.get("inheritance");
        if (l != null) {
            treatInheritance((Node) l.get(0), c);
        }
        l = (List) classChildren.get("version");
        if (l != null) {
            treatVersion((Node) l.get(0), c);
        }
        l = (List) classChildren.get("join");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                Object[] os = getJoin((Node) l.get(j), null);
                SpeedoJoin join = (SpeedoJoin) os[0];
                String tableName = (String) os[1];
                //define an external/secondary table
                c.addJoin(join);
                if (c.mainTable != null) {
                    join.mainTable = c.mainTable;
                }
                if (tableName != null) {
                    join.extTable = new SpeedoTable();
                    join.extTable.name = tableName;
                    join.extTable.join = join;
                }
            }           
        }
        l = (List) classChildren.get("field");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                treatFieldNode((Node) l.get(j), c);
            }
        }
        l = (List) classChildren.get("query");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                SpeedoPredefinedQuery spq = getQuery((Node) l.get(j));
                c.name2query.put(spq.name, spq);
            }
        }
        l = (List) classChildren.get("index");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                treatIndexNode((Node) l.get(j), c);
            }
        }
        l = (List) classChildren.get("fetch-group");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                treatFetchGroupNode((Node) l.get(j), c);
            }
        }
       
        //TODO: unmanaged stuff of class
        unmanaged(null, new String[]{"foreign-key", "unique"},
                classNode,  classChildren);
    }
    private void treatDataStoreId(Node dsiNode, SpeedoClass moClass) throws SpeedoException {
        SpeedoIdentity ident = new SpeedoIdentity(); //default strategy is native
        //<!ATTLIST datastore-identity strategy CDATA 'native'>
        Node n = dsiNode.getAttributes().getNamedItem("strategy");
        if (n == null)
            throw new SpeedoXMLError("Attribute strategy for tag datastore-identity requested.");
        ident.strategy = SpeedoIdentity.getStrategy(n.getNodeValue());

        //<!ATTLIST datastore-identity sequence CDATA #IMPLIED>
        n = dsiNode.getAttributes().getNamedItem("sequence");
        if (n != null)
            ident.sequenceName = n.getNodeValue();
         
        //<!ATTLIST datastore-identity column CDATA #IMPLIED>
        List columns = null;
        n = dsiNode.getAttributes().getNamedItem("column");
        if (n != null) {
            columns = new ArrayList();
            columns.add(new SpeedoColumn(n.getNodeValue()));
           
        }
        //<!ELEMENT datastore-identity (extension*, column*, extension*)>
        //inner element column
        Map dsiChildren = groupChildrenByName(dsiNode);
        treatExtensions((List) dsiChildren.get("extension"), ident);
        //TODO: unmanaged stuff of class
        unmanaged(null, new String[]{"index", "unique", "fetch-group"},
                dsiNode,  dsiChildren);
        List columnNodes = (List) dsiChildren.get("column");
        if (columnNodes != null) {
          for (int i = 0; i < columnNodes.size(); i++) {
              if (columns == null) {
                  columns = new ArrayList();
              }
              Node columnNode = (Node) columnNodes.get(i);
              columns.add(getColumn(columnNode));
          }
        }
        if (columns != null) {
            moClass.identity.setColumns(columns);
        }
        //bind the identity to the moClass
        moClass.identity = ident;
        if (debug) {
            logger.log(BasicLevel.DEBUG, "New datastore-identity: "
                + "identity=" + ident);
        }
    }
    private void treatInheritance(Node inhNode, SpeedoClass moClass) throws SpeedoException {
        if (moClass.inheritance == null) {
            moClass.inheritance = new SpeedoInheritance(moClass);
        }
        //<!ATTLIST inheritance strategy CDATA #IMPLIED>
        Node n = inhNode.getAttributes().getNamedItem("strategy");
        if (n != null) {
            moClass.inheritance.strategy =
                SpeedoInheritance.parseStrategy(n.getNodeValue());
            logger.log(BasicLevel.DEBUG, "defines the strategy '"
                    + SpeedoInheritance.strategy2str(moClass.inheritance.strategy));
        }
        //<!ELEMENT inheritance (extension*, join?, discriminator?, extension*)>
        Map inhChildren = groupChildrenByName(inhNode);
        //inner element extension
        treatExtensions((List) inhChildren.get("extension"), moClass.inheritance);
        //inner element join
        List l = (List) inhChildren.get("join");
        if (l != null) {
            //define a join to the super class (vertical mapping)
            Object[] os = getJoin((Node) l.get(0), null);
            moClass.inheritance.join = (SpeedoJoin) os[1];
        }
        //inner element discriminator
        l = (List) inhChildren.get("discriminator");
        if (l != null) {
            treatDiscriminator((Node) l.get(0), moClass.inheritance);
        }
    }
    private void treatDiscriminator(Node discNode, SpeedoInheritance inh)throws SpeedoException {
        if (inh.discriminator == null) {
            inh.discriminator = new SpeedoDiscriminator();
        }
        //<!ATTLIST discriminator strategy CDATA #IMPLIED>
        Node n = discNode.getAttributes().getNamedItem("strategy");
        if (n != null) {
            inh.discriminator.strategy =
                SpeedoDiscriminator.parseStrategy(n.getNodeValue());
        }
        //<!ELEMENT discriminator (extension*, column*, index?, extension*)>
        //inner element extension
        Map discChildren = groupChildrenByName(discNode);

        //<!ATTLIST discriminator value CDATA #IMPLIED>
        n = discNode.getAttributes().getNamedItem("value");
        String val = null;
        if (n != null) {
            val = n.getNodeValue();
        }
       
        //<!ATTLIST discriminator column CDATA #IMPLIED>
        n = discNode.getAttributes().getNamedItem("column");
        SpeedoColumn col = null;
        if (n != null) {
            col = new SpeedoColumn(n.getNodeValue());
        } else {
            //inner element column
            List columnNodes = (List) discChildren.get("column");
            if (columnNodes != null && columnNodes.size() == 1) {
                Node columnNode = (Node) columnNodes.get(0);
                col = getColumn(columnNode);
            }
        }
        if (col == null) {
            if (val != null) {
                //try to use the default column
               
            }
        } else {
            if (val != null) {
               
            } else {
                //column definition on abstract class
            }
        }
        SpeedoNoFieldColumn snfc = new SpeedoNoFieldColumn();
        snfc.column = col;
        inh.discriminator.elements.add(snfc);
        if (val != null) {
            if (inh.discriminatorValues == null) {
                inh.discriminatorValues = new HashMap();
            }
            inh.discriminator.setDiscriminatorValue(val, inh, snfc);
        }
       
        treatExtensions((List) discChildren.get("extension"),
                inh.discriminator);
        unmanaged(new String[]{"indexed"}, new String[]{"index"},
                discNode, discChildren);
    }
    private Object[] getJoin(Node joinNode, SpeedoJoin j) throws SpeedoException {
        Node n = joinNode.getAttributes().getNamedItem("table");
        if (j == null) {
            j = new SpeedoJoin();
        }
        n = joinNode.getAttributes().getNamedItem("delete-action");
        if (n != null) {
            String v = n.getNodeValue();
            if ("restrict".equals(v)) {
                j.deleteAction = SpeedoJoin.ACTION_RESTRICT;
            } else if ("cascade".equals(v)) {
                j.deleteAction = SpeedoJoin.ACTION_CASCADE;
            } else if ("null".equals(v)) {
                j.deleteAction = SpeedoJoin.ACTION_NULL;
            } else if ("none".equals(v)) {
                j.deleteAction = SpeedoJoin.ACTION_NONE;
            } else if ("default".equals(v)) {
                j.deleteAction = SpeedoJoin.ACTION_DEFAULT;
            } else {
                j.deleteAction = SpeedoJoin.ACTION_DEFAULT;
            }
        }
        j.setUnique(getBooleanAttributeValue(joinNode, "unique", j.getUnique()));
        j.setIndexed(getBooleanAttributeValue(joinNode, "indexed", j.getIndexed()));
        j.setOuter(getBooleanAttributeValue(joinNode, "indexed", j.getOuter()));
        n = joinNode.getAttributes().getNamedItem("column");
        if (n != null) {
          SpeedoJoinColumn sjc = new SpeedoJoinColumn(new SpeedoColumn(n.getNodeValue()));
            j.columns.add(sjc);
        }
        Map joinChildren = groupChildrenByName(joinNode);
        List l = (List) joinChildren.get("column");
        if (l != null) {
            for (int i = 0; i < l.size(); i++) {
                j.columns.add(new SpeedoJoinColumn(getColumn((Node) l.get(i))));
            }
        }
        n = joinNode.getAttributes().getNamedItem("table");
        String tableName = null;
        if (n != null) {
            tableName = n.getNodeValue();
        }
        return new Object[]{j, tableName};
    }
    private void treatVersion(Node versionNode, SpeedoClass moClass) throws SpeedoException {
        SpeedoVersion v = new SpeedoVersion();
        //attribute embedded-element
        //<!ATTLIST version strategy CDATA #IMPLIED>
        Node n = versionNode.getAttributes().getNamedItem("strategy");
        v.strategy = SpeedoVersion.toByte(n.getNodeValue());

        //<!ATTLIST version indexed (true|false|unique) #IMPLIED>
        n = versionNode.getAttributes().getNamedItem("strategy");
        if (n != null) {
            //TODO: Speedo does not support yet the indexed attribute in version tag
            logger.log(BasicLevel.WARN, "Speedo does not support yet the indexed attribute in version tag");
        }

        //<!ATTLIST version column CDATA #IMPLIED>
        List columns = null;
        n = versionNode.getAttributes().getNamedItem("column");
        if (n != null) {
            columns = new ArrayList();
            columns.add(new SpeedoColumn(n.getNodeValue()));
        }
        //<!ELEMENT version (extension*, column*, index?, extension*)>
        Map versionChildren = groupChildrenByName(versionNode);
        unmanaged(new String[]{"column"}, new String[]{"column", "index"},
                versionNode, versionChildren);
        moClass.version = v;
        logger.log(BasicLevel.DEBUG, "New version: strategy=" + v.strategy);  
    }
    private void treatExtensions(List nodes, SpeedoElement se) throws SpeedoException {
        if (nodes != null) {
            for (int i = 0; i < nodes.size(); i++) {
                treatExtension((Node) nodes.get(i), se);
            }
        }
    }
    private void treatExtension(Node node, SpeedoElement se) throws SpeedoException {
        SpeedoExtension e = new SpeedoExtension();
        //<!ATTLIST extension vendor-name CDATA #REQUIRED>
        Node n = node.getAttributes().getNamedItem("vendor-name");
        e.vendorName = n.getNodeValue();
        //<!ATTLIST extension key CDATA #IMPLIED>
        n = node.getAttributes().getNamedItem("key");
        if (n != null) {
            e.key = n.getNodeValue();
        }
        //<!ATTLIST extension value CDATA #IMPLIED>
        n = node.getAttributes().getNamedItem("value");
        if (n != null) {
            e.value = n.getNodeValue();
        }
        //<!ELEMENT extension ANY>
       
        logger.log(BasicLevel.DEBUG, "Parse extension name=" + e.key + ", value=" + e.value);
        se.addExtension(e);
        e.owner = se;
    }
    private SpeedoColumn getColumn(Node node) throws SpeedoException {
        SpeedoColumn c = new SpeedoColumn();
        Node n = node.getAttributes().getNamedItem("name");
        if (n != null) {
            c.name = n.getNodeValue();
        }
        n = node.getAttributes().getNamedItem("target");
        if (n != null) {
            c.targetColumn = n.getNodeValue();
        }
        n = node.getAttributes().getNamedItem("target-field");
        if (n != null) {
            c.targetField = n.getNodeValue();
        }
        n = node.getAttributes().getNamedItem("jdbc-type");
        if (n != null) {
            c.jdbcType = n.getNodeValue();
        }
        n = node.getAttributes().getNamedItem("sql-type");
        if (n != null) {
            c.sqlType = n.getNodeValue();
        }
        n = node.getAttributes().getNamedItem("length");
        if (n != null) {
            c.length = Integer.parseInt(n.getNodeValue());
        }
        n = node.getAttributes().getNamedItem("scale");
        if (n != null) {
            c.scale = Integer.parseInt(n.getNodeValue());
        }
        c.allowNull = getBooleanAttributeValue(node, "allows-null", c.allowNull);
        n = node.getAttributes().getNamedItem("default-value");
        if (n != null) {
            c.defaultValue = n.getNodeValue();
        }
        return c;
    }       
    private SpeedoPredefinedQuery getQuery(Node queryNode) throws SpeedoException {
        //TODO: verify DTD about query
        SpeedoPredefinedQuery spq = new SpeedoPredefinedQuery();
        //<!ATTLIST query name CDATA #IMPLIED>
        spq.name = getStringAttributeValue(queryNode, "name", null);
        //<!ATTLIST query language CDATA #IMPLIED>
        spq.language = getStringAttributeValue(queryNode, "language", null);
        //<!ELEMENT query (#PCDATA|extension)*>
        spq.query = queryNode.getNodeValue();
        Map queryChildren = groupChildrenByName(queryNode);
        treatExtensions((List) queryChildren.get("extension"), spq);
        return spq;
    }
    private SpeedoFetchGroup getFetchGroup(Node fgNode, SpeedoClass fieldOwner) throws SpeedoException {
        SpeedoFetchGroup fg = new SpeedoFetchGroup();
        //<!ATTLIST fetch-group name CDATA #REQUIRED>
        Node n = fgNode.getAttributes().getNamedItem("name");
        fg.name = n.getNodeValue();
       
        //<!ATTLIST fetch-group post-load (true|false) #IMPLIED>
        n = fgNode.getAttributes().getNamedItem("post-load");
        if (n != null){
            fg.postLoad = Boolean.valueOf(n.getNodeValue()).booleanValue();
        } else {
            if (fg.name.equals("default")) {
                fg.postLoad = true;
            } else {
                fg.postLoad = false;
            }
        }
        Map fgChildren = groupChildrenByName(fgNode);
        //<!ELEMENT fetch-group (fetch-group|field)*>
        List l = (List) fgChildren.get("field");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                Node fieldNode = (Node) l.get(j);
                String fieldName = getStringAttributeValue(fieldNode, "name", null);
                if (fieldName != null) {
                    SpeedoField field = fieldOwner.getField(fieldName);
                    if (field != null) {
                        fg.addField(field);
                    } else {
                        logger.log(BasicLevel.WARN, "Bad field name '"
                                + fieldName + "'in the fetch group '"
                                + fg.name + "' in the class "
                                + fieldOwner.getSourceDesc() + ".");
                    }
                }
            }           
        }
        l = (List) fgChildren.get("fetch-group");
        if (l != null) {
            for (int j = 0; j < l.size(); j++) {
                SpeedoFetchGroup subfg = getFetchGroup((Node) l.get(j), fieldOwner);
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, "add fetchgroup '"
                            +  subfg.name + "' into the fetchgroup '"
                            + fg.name +"'");
                }
                fg.addFetchGroup(subfg);
            }           
        }
        return fg;
    }
   
    private void treatFieldNode(Node fieldNode, SpeedoClass moClass, SpeedoIndex moIndex) throws SpeedoException {
      //at the moment, only support for field with name attribute
      //no support for field definition within the index tag
      Node n = null;

    //<!ATTLIST field name CDATA #REQUIRED>
        n = fieldNode.getAttributes().getNamedItem("name");
        if (n == null)
            throw new SpeedoXMLError("Attribute name for tag field requested.");
        String name = n.getNodeValue();
        //add the field name to the index
        moIndex.fieldNames.add(name);
        //try to add the column name(s) to the index
        SpeedoField sf = (SpeedoField) moClass.fields.get(name);
        if (sf == null)
          throw new SpeedoXMLError("The field " + name + " must be defined for the class "
              + moClass.name +".");
        if( sf.columns != null  && sf.columns.length != 0) {
          for(int i = 0; i < sf.columns.length; i++) {
            moIndex.columnNames.add(sf.columns[i].name);
          }
        } else {
          logger.log(BasicLevel.WARN, "The column(s) for the field " + name + " has not been defined yet." )
        }
    }
   
    private void treatFieldNode(Node fieldNode, SpeedoClass moClass) throws SpeedoException {
    Node n = null;

    //<!ATTLIST field name CDATA #REQUIRED>
        n = fieldNode.getAttributes().getNamedItem("name");
        if (n == null)
            throw new SpeedoXMLError("Attribute name for tag field requested.");
        String name = n.getNodeValue();
        int dotIdx = name.lastIndexOf(".");
        SpeedoField f = null;
        SpeedoCommonField cf;
        FieldContext fc = new FieldContext();
        fc.fieldNode = fieldNode;
        if(dotIdx != -1){
            cf = moClass.inheritance.newSpeedoInheritedField(name);
        } else {
            f = new SpeedoField();
            cf = f;
          f.name = n.getNodeValue();
            f.moClass = moClass;
 
          //<!ATTLIST field persistence-modifier (persistent|transactional|none) #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("persistence-modifier");
          if (n != null)
              f.persistenceStatus = SpeedoField.parsePersistenceStatus(n.getNodeValue());
 
      //<!ATTLIST field primary-key (true|false) 'false'>
          n = fieldNode.getAttributes().getNamedItem("primary-key");
          if (n != null)
              f.primaryKey = Boolean.valueOf(n.getNodeValue()).booleanValue();
 
      //<!ATTLIST field null-value (exception|default|none) 'none'>
          n = fieldNode.getAttributes().getNamedItem("null-value");
          if (n != null) {
              f.nullValue = SpeedoNullValue.toByte(n.getNodeValue());
          }
 
      //<!ATTLIST field default-fetch-group (true|false) #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("default-fetch-group");
          if (n != null)
              f.defaultFetchGroup = Boolean.valueOf(n.getNodeValue()).booleanValue();
 
          //attribute fetch-group
          n = fieldNode.getAttributes().getNamedItem("fetch-group");
          if (n != null)
              f.fetchGroup = n.getNodeValue();
             
      //<!ATTLIST field fetch-depth CDATA #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("fetch-depth");
          if (n == null) {
              n = fieldNode.getAttributes().getNamedItem("depth");
              if (n != null) {
                  logger.log(BasicLevel.WARN, "attribute 'depth' is deprecated, use 'fetch-depth'.");
              }
          }
          if (n != null) {
              f.depth = Integer.valueOf(n.getNodeValue()).intValue();
          }           
 
      //<!ATTLIST field embedded (true|false) #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("embedded");
          if (n != null)
              f.embedded = Boolean.valueOf(n.getNodeValue()).booleanValue();
 
      //<!ATTLIST field value-strategy CDATA #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("value-strategy");
          if (n != null)
              f.valueStrategy = n.getNodeValue();
         
      //<!ATTLIST field sequence CDATA #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("sequence");
          if (n != null)
              f.sequence = n.getNodeValue();
         
      //<!ATTLIST field mapped-by CDATA #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("mapped-by");
          if (n != null) {
              f.reverseField = n.getNodeValue();
              f.mappedByReversefield = true;
              f.isCoherentReverseField = true;
              if (logger.isLoggable(BasicLevel.DEBUG)) {
                  logger.log(BasicLevel.DEBUG, "The field " + f.name
                      + " is mapped by " + f.reverseField);
              }
          }
        }
        fc.field = cf;
       
        //<!ATTLIST field table CDATA #IMPLIED>
        fc.parseTableAttribute(fieldNode, logger);

        //<!ELEMENT field (extension*, (array|collection|map)?, join?,
        //embedded?, element?, key?, value?, order?, column*, foreign-key?,
        //index?, unique?, extension*)>

        fc.fieldChildren = groupChildrenByName(fieldNode);
        List l;
        treatExtensions((List) fc.fieldChildren.get("extension"), cf);

        if (fc.parseORM()) {
            //Parse the O/R mapping of the [inherited] field
            l = (List) fc.fieldChildren.get("join");
            if (l != null) {
                //define an external/secondary table used by a particular field
                Object[] os = getJoin((Node) l.get(0), fc.join);
                fc.join = (SpeedoJoin) os[0];
                if (f != null) {
                    logger.log(BasicLevel.DEBUG, "Specify the join " + fc.join
                             + " to the field " + f.name);
                } else if (logger.isLoggable(BasicLevel.DEBUG)) {
                    logger.log(BasicLevel.DEBUG, "Specify the join " + fc.join
                            + " to the inherited field " + cf.name);
                }
            }
          //<!ATTLIST field column CDATA #IMPLIED>
          n = fieldNode.getAttributes().getNamedItem("column");
          if (n != null) {
              fc.addColumn(new SpeedoColumn(n.getNodeValue()));
          }
          l = (List) fc.fieldChildren.get("column");
          if (l != null) {
              for (int i = 0; i < l.size(); i++) {
                  fc.addColumn(getColumn((Node) l.get(i)));
              }
          }
        }
        boolean isCollection = fc.fieldChildren.get("collection") != null
          || fc.fieldChildren.get("element") != null
          ;
      boolean isMap = fc.fieldChildren.get("map") != null
      || fc.fieldChildren.get("key") != null
      || fc.fieldChildren.get("value") != null
        ;
      boolean isArray = fc.fieldChildren.get("array") != null;
      if (isMap) {
          if (isCollection) {
              logger.log(BasicLevel.WARN, "The '" + f.name
                      + "' from the class '" + moClass.getFQName()
                      + "' cannot be a map AND a collection !");
          }
      }
      if (isCollection) {
          treatCollectionField(fc);
      } else if (isMap) {
          treatMapField(fc);
      } else if (isArray) {
         
      } else {
          treatSimpleField(fc);
      }
        unmanaged(new String[]{"serialized", "dependent", "delete-action",
                        "load-fetch-group", "foreign-key", "indexed", "unique"},
                new String[]{"embedded", "order", "foreign-key", "unique",
                "index", "array"},
                fieldNode,  fc.fieldChildren);
        if (f != null) {
            if (debug) {
                logger.log(BasicLevel.DEBUG, "New field: "
                    + "name=" + f.name
                    + "  / persistenceModifier = " + f.persistenceStatus
                    + "  / primaryKey = " + f.primaryKey
                    + "  / nullValue = " + f.nullValue
                    + "  / defaultFetchGroup = " + f.defaultFetchGroup
                    + "  / embedded = " + f.embedded
                    + "  / depth = " + f.depth
                    + "  / valueStrategy = " + f.valueStrategy
                    + "  / sequence = " + f.sequence
                );
            }
            moClass.add(f, true, logger);
        } //else it is an inherited field already attached to moClass.inheritance
    }
    private void treatMapField(FieldContext fc) throws SpeedoException {
        SpeedoMap m = (SpeedoMap) fc.field.jdoTuple;
        if (m == null) {
            m = new SpeedoMap();
        }
        fc.field.jdoTuple = m;
        m.moField = (SpeedoField) fc.field;
        List l = (List) fc.fieldChildren.get("map");
        if (l != null) {
          l = (List) fc.fieldChildren.get("map");
          Node mapNode = (Node) l.get(0);
          //attribut key-type
          Node n = mapNode.getAttributes().getNamedItem("key-type");
          if (n != null)
              m.keyType = n.getNodeValue();
          //attribut embedded-key
          n = mapNode.getAttributes().getNamedItem("embedded-key");
          if (n != null)
              m.embeddedKey = Boolean.valueOf(n.getNodeValue()).booleanValue();
          //attribute value-type
          n = mapNode.getAttributes().getNamedItem("value-type");
          if (n != null)
              m.valueType = n.getNodeValue();
          //attribute embedded-value
          n = mapNode.getAttributes().getNamedItem("embedded-value");
          if (n != null)
              m.embeddedValue = Boolean.valueOf(n.getNodeValue()).booleanValue();
        }

        l = (List) fc.fieldChildren.get("key");
        if (l != null) {
            //<!ELEMENT key (extension*, embedded?, column*, foreign-key?, index?, unique?, extension*)>
            //<!ATTLIST key table CDATA #IMPLIED>
            //<!ATTLIST key serialized (true|false) #IMPLIED>
            //<!ATTLIST key delete-action (restrict|cascade|null|default|none) #IMPLIED>
            //<!ATTLIST key indexed (true|false|unique) #IMPLIED>
            //<!ATTLIST key unique (true|false) #IMPLIED>
            Node keyNode = (Node) l.get(0);
            Map keyChildren = groupChildrenByName(keyNode);
            if (fc.parseORM()) {
                //<!ATTLIST key column CDATA #IMPLIED>
              Node n = keyNode.getAttributes().getNamedItem("column");
              if (n != null) {
                  SpeedoColumn col = new SpeedoColumn(n.getNodeValue());
                  //in the same table than map value
                  if (fc.field.columns != null && fc.field.columns.length > 0) {
                      col.table = fc.field.columns[0].table;
                  }
                  m.keyColumns = col;
              }
              l = (List) keyChildren.get("column");
              if (l != null) {
                  m.keyColumns = getColumn((Node) l.get(0));
              }
              fc.parseTableAttribute(keyNode, logger);
            }
            unmanaged(
                    new String[]{"serialized", "delete-action", "indexed", "unique"},
                    new String[]{"embedded", "foreign-key", "unique", "index"},
                    keyNode, keyChildren);
        }
        l = (List) fc.fieldChildren.get("value");
        if (l != null) {
            //<!ELEMENT value (extension*, embedded?, column*, foreign-key?, index?, unique?, extension*)>
            //<!ATTLIST value serialized (true|false) #IMPLIED>
            //<!ATTLIST value table CDATA #IMPLIED>
            //<!ATTLIST value delete-action (restrict|cascade|null|default|none) #IMPLIED>
            //<!ATTLIST value indexed (true|false|unique) #IMPLIED>
            //<!ATTLIST value unique (true|false) #IMPLIED>
            Node valueNode = (Node) l.get(0);
            Map valueChildren = groupChildrenByName(valueNode);
            if (fc.parseORM()) {
                //<!ATTLIST value column CDATA #IMPLIED>
              Node n = valueNode.getAttributes().getNamedItem("column");
              if (n != null) {
                fc.addColumn(new SpeedoColumn(n.getNodeValue()));
              }
              l = (List) valueChildren.get("column");
              if (l != null) {
                  for (int i = 0; i < l.size(); i++) {
                      fc.addColumn(getColumn((Node) l.get(i)));
                  }
              }
              fc.parseTableAttribute(valueNode, logger);
            }
            unmanaged(
                    new String[]{"serialized", "delete-action", "indexed", "unique"},
                    new String[]{"embedded", "foreign-key", "unique", "index"},
                    valueNode, valueChildren);
        }
        if (fc.join != null && fc.field.moClass.containsJoin(fc.join)) {
            fc.field.moClass.removeJoin(fc.join);
        }
        logger.log(BasicLevel.DEBUG, "New map: "
                + "keyType=" + m.keyType
                + "  / embeddedKey = " + m.embeddedKey
                + "  / valueType = " + m.valueType
                + "  / embeddedValue = " + m.embeddedValue
        );
    }
    private void treatCollectionField(FieldContext fc) throws SpeedoException {
        List l = (List) fc.fieldChildren.get("collection");
        if (l != null) {
            Node collectionNode = (Node) l.get(0);
          SpeedoCollection co = (SpeedoCollection) fc.field.jdoTuple;
          if (co == null) {
              co = new SpeedoCollection();
          }
          fc.field.jdoTuple = co;
          co.moField = (SpeedoField) fc.field;
          //attribute element-type
          Node n = collectionNode.getAttributes().getNamedItem("element-type");
          if (n != null)
              co.elementType = n.getNodeValue();
 
          //attribute embedded-element
          n = collectionNode.getAttributes().getNamedItem("embedded-element");
          if (n != null) {
              co.embeddedElement = Boolean.valueOf(n.getNodeValue()).booleanValue();
          }
          if (debug) {
              logger.log(BasicLevel.DEBUG, "New collection: "
                  + "elementType=" + co.elementType
                  + "  / embeddedElement = " + co.embeddedElement
              );
          }
        }
        l = (List) fc.fieldChildren.get("element");
        if (l != null) {
            //<!ATTLIST element column CDATA #IMPLIED>
            Node elementNode = (Node) l.get(0);
            //<!ELEMENT element (extension*, embedded?, column*, foreign-key?,
            // index?, unique?, extension*)>
            Map elementChildren = groupChildrenByName(elementNode);
            if (fc.parseORM()) {
              Node n = elementNode.getAttributes().getNamedItem("column");
              if (n != null) {
                  fc.addColumn(new SpeedoColumn(n.getNodeValue()));
              }
              l = (List) elementChildren.get("column");
              if (l != null) {
                  for (int i = 0; i < l.size(); i++) {
                      fc.addColumn(getColumn((Node) l.get(i)));
                  }
              }
              //<!ATTLIST element table CDATA #IMPLIED>
              n = elementNode.getAttributes().getNamedItem("table");
              if (n != null) {
                  if (fc.table == null) {
                      fc.table = new SpeedoTable();
                  } else {
                      logger.log(BasicLevel.WARN, "Specify two tables for the "
                              + fc.field.getSourceDesc()
                              + ": " + fc.table.name + " and " + n.getNodeValue())
                  }
                  fc.table.name = n.getNodeValue();
              }
            }
           
            unmanaged(new String[]{"serialized", "delete-action",
                    "update-action", "indexed", "unique"},
                    new String[]{"embedded", "foreign-key", "unique", "index"},
                    elementNode,  fc.fieldChildren);
        }
        if (!fc.parseORM()) {
            return;
        }
        if (fc.join != null && fc.field.moClass.containsJoin(fc.join)) {
            fc.field.moClass.removeJoin(fc.join);
        }
        if (fc.table != null || fc.join != null) {
            // The collection is stored in a join table
            if (fc.join == null) {
                // the user specified a table without join. Maybe the join to
                // this table is already defined at class level
                SpeedoJoin[] js = fc.field.moClass.joinToExtTables;
                if (js != null) {
                    for (int i = 0; i < js.length; i++) {
                        if (js[i].extTable != null && fc.table.name.equals(js[i].extTable.name)) {
                            //The join to this table is already defined at class level
                            // use it
                            fc.field.join = js[i];
                            i = js.length;
                        }
                    }
                    if (fc.field.join == null) {
                        //no existing join found, create a new one
                        fc.join = new SpeedoJoin();
                    }
                }
            }
            fc.field.join = fc.join;
            fc.field.join.extTable = fc.table;
            fc.field.join.mainTable = fc.field.moClass.mainTable;
        } else {
            // The collection is stored in the table of the referenced state
            fc.field.join = new SpeedoJoin();
        }
        fc.field.columns = fc.getColumns();
    }
    private void treatSimpleField(FieldContext fc) {
        if (!fc.parseORM()) {
            return;
        }
        //The field is a primitive field OR a mono valued reference to
        // another persistent class
        if (fc.join != null) { //join sub element specified
            if (fc.table == null) { //no table name specified in field
                fc.table = new SpeedoTable();
                //allocate a defaut name for the secondary table
                fc.table.name = fc.field.moClass.name.toUpperCase()
                  + "_" + fc.field.name.toUpperCase();
            }
            fc.field.join = fc.join;
            fc.field.join.extTable = fc.table;
            fc.field.join.mainTable = fc.field.moClass.mainTable;
            if (!fc.field.moClass.containsJoin(fc.field.join)) {
                fc.field.moClass.addJoin(fc.field.join);
            }
        } else if (fc.table != null) {
            if (fc.field.moClass.mainTable != null
                    && fc.table.name.equals(fc.field.moClass.mainTable.name)) {
                //the user specified the same table than the main table
                // without join.
                fc.table = null;
            }
            if (fc.table != null) {
                logger.log(BasicLevel.INFO,
                        "The user specified a secondary table without join columns");
                if (fc.field.moClass.getExtTable(fc.table.name, false) != fc.table) {
                    logger.log(BasicLevel.INFO,
                    "The user specified a secondary table without join columns");
                    fc.field.join = new SpeedoJoin();
                    fc.field.join.mainTable = fc.field.moClass.mainTable;
                    fc.field.join.extTable = fc.table;
                    fc.field.moClass.addJoin(fc.field.join);
                } else {
                    logger.log(BasicLevel.DEBUG, "Field '" + fc.field.name
                            + " is mapped into the table '"
                            + fc.table.name + "'.");
                }
            }
        }
        if (fc.table == null) {
            fc.table = fc.field.moClass.mainTable;
        }
        if (fc.columns != null) {
            for (int i = 0; i < fc.columns.size(); i++) {
                SpeedoColumn column = (SpeedoColumn) fc.columns.get(i);
                if (column.table == null) {
                    column.table = fc.table;
                }
                fc.field.addColumn(column);
                logger.log(BasicLevel.DEBUG, "specify column " + column.name
                        + " to the field " + fc.field.name + ": " + fc.field.columns);
            }
        } else {
            //no column specified, the mapping will be defined later
            // when we will have more information about the field type.
        }
       
    }
    private void treatFetchGroupNode(Node fetchNode, SpeedoClass moClass) throws SpeedoException {
        SpeedoFetchGroup fg = treatFetchGroupTree(fetchNode, moClass);
        moClass.fetchGroups.put(fg.name, fg);
    }
    private SpeedoFetchGroup treatFetchGroupTree(Node fetchNode,
            SpeedoClass fieldOwner) throws SpeedoException {
        //<!ELEMENT fetch-group (fetch-group|field)*>
        SpeedoFetchGroup fg = new SpeedoFetchGroup();
        //<!ATTLIST fetch-group name CDATA #REQUIRED>
        fg.name = getStringAttributeValue(fetchNode, "name", null);
        //<!ATTLIST fetch-group post-load (true|false) #IMPLIED>
        fg.postLoad = getBooleanAttributeValue(fetchNode, "post-load", false);
        Map fgChildren = groupChildrenByName(fetchNode);
        List fgs = (List) fgChildren.get("fetch-group");
        if (fgs != null) {
          for (Iterator fgIt = fgs.iterator(); fgIt.hasNext();) {
              Node fgNode = (Node) fgIt.next();
              fg.addFetchGroup(treatFetchGroupTree(fgNode, fieldOwner));
          }
        }
       
        List fields = (List) fgChildren.get("field");
        if (fields != null) {
          for (Iterator fieldIt = fields.iterator(); fieldIt.hasNext();) {
              Node fieldNode = (Node) fieldIt.next();
              SpeedoField sf = new SpeedoField();
              sf.name = getStringAttributeValue(fieldNode, "name", null);
                fg.addField(sf);
                //depth for a field
                String depth = getStringAttributeValue(fieldNode, "fetch-depth", null);
                if (depth == null) {
                  depth = getStringAttributeValue(fieldNode, "depth", null);
                  logger.log(BasicLevel.WARN, "attribute 'depth' is deprecated, use 'fetch-depth'.");
                }
                if (depth != null) {
                  sf.depth = new Integer(depth).intValue();
                }       
          }
        }
        return fg;
    }
    private static String getStringAttributeValue(Node node, String attribName, String defaultValue) {
        Node n = node.getAttributes().getNamedItem(attribName);
        if (n != null) {
            return n.getNodeValue();
        } else {
            return defaultValue;
        }
    }
    private static boolean getBooleanAttributeValue(Node node, String attribName, boolean defaultValue) {
        Node n = node.getAttributes().getNamedItem(attribName);
        if (n != null) {
            return Boolean.valueOf(n.getNodeValue()).booleanValue();
        } else {
            return defaultValue;
        }
    }
    private void unmanaged(String[] attributeNames,
            String[] nodeTypes,
            Node node,
            Map type2nodes) {
        String parent = node.getNodeName();
        if (attributeNames != null) {
          for (int i = 0; i < attributeNames.length; i++) {
              Node n = node.getAttributes().getNamedItem(attributeNames[i]);
              if (n != null) {
                  logger.log(BasicLevel.WARN, "Speedo does not support yet the "
                              + attributeNames[i] + " attribute in "
                              + parent + " tag.");
              }
          }
        }
        if (nodeTypes != null) {
          for (int i = 0; i < nodeTypes.length; i++) {
              List l = (List) type2nodes.get(nodeTypes[i]);
              if (l != null) {
                  for (int j = 0; j < l.size(); j++) {
                      logger.log(BasicLevel.WARN, "Speedo does not support yet the "
                              + nodeTypes[i] + " sub element in "
                              + parent + " tag.");
                  }
              }
          }
        } 
    }
    private static class FieldContext {
        /**
         * The Speedo meta object representing the field:
         * SpeedoField or SpeedoInheritedField
         */
        public SpeedoCommonField field;
        /**
         * The join found associated to this field
         */
        public SpeedoJoin join;
        /**
         * The table instance
         */
        public SpeedoTable table;
        public List columns;
        public List idxColumns;
        public Node fieldNode;
        public Map fieldChildren;
        public void addColumn(SpeedoColumn col) {
            if (columns == null) {
                columns = new ArrayList();
            }
            columns.add(col);
        }
        public boolean parseORM() {
            return !(field instanceof SpeedoField)
                    || !((SpeedoField) field).mappedByReversefield;
        }
        public void parseTableAttribute(Node node, Logger logger) {
            Node n = fieldNode.getAttributes().getNamedItem("table");
            if (n != null) {
                join = field.moClass.getJoin(n.getNodeValue(), true);
                table = join.extTable;
                if (logger.isLoggable(BasicLevel.DEBUG)) {
                    if (field instanceof SpeedoField) {
                      logger.log(BasicLevel.DEBUG, "specify table " + table.name
                              + " to the field " + field.name + ": " + field.columns);
                    } else {
                        logger.log(BasicLevel.DEBUG, "specify table " + table.name
                                + " to the inherited field " + field.name
                                + ": " + field.columns);
                    }
                }
            }
        }
        public SpeedoColumn[] getColumns() {
            if (columns == null || columns.size() == 0) {
                return null;
            } else {
                return (SpeedoColumn[]) columns.toArray(new SpeedoColumn[columns.size()]);
            }
        }
    }
}
TOP

Related Classes of org.objectweb.speedo.generation.parser.jdo.JDO2Parser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.