Source Code Cross Referenced for JDO2Parser.java in  » Database-ORM » Speedo_1.4.5 » org » objectweb » speedo » generation » parser » jdo » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » Speedo_1.4.5 » org.objectweb.speedo.generation.parser.jdo 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * Speedo: an implementation of JDO compliant personality on top of JORM generic
0003:         * I/O sub-system.
0004:         * Copyright (C) 2001-2004 France Telecom R&D
0005:         *
0006:         * This library is free software; you can redistribute it and/or
0007:         * modify it under the terms of the GNU Lesser General Public
0008:         * License as published by the Free Software Foundation; either
0009:         * version 2 of the License, or (at your option) any later version.
0010:         *
0011:         * This library is distributed in the hope that it will be useful,
0012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         * Lesser General Public License for more details.
0015:         *
0016:         * You should have received a copy of the GNU Lesser General Public
0017:         * License along with this library; if not, write to the Free Software
0018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0019:         *
0020:         * Contact: speedo@objectweb.org
0021:         * Authors: S.Chassande-Barrioz.
0022:         *
0023:         */package org.objectweb.speedo.generation.parser.jdo;
0024:
0025:        import java.util.ArrayList;
0026:        import java.util.Collections;
0027:        import java.util.HashMap;
0028:        import java.util.Iterator;
0029:        import java.util.List;
0030:        import java.util.Map;
0031:
0032:        import org.objectweb.speedo.api.SpeedoException;
0033:        import org.objectweb.speedo.generation.api.SpeedoXMLError;
0034:        import org.objectweb.speedo.generation.parser.AbstractParser;
0035:        import org.objectweb.speedo.lib.Personality;
0036:        import org.objectweb.speedo.metadata.SpeedoClass;
0037:        import org.objectweb.speedo.metadata.SpeedoCollection;
0038:        import org.objectweb.speedo.metadata.SpeedoColumn;
0039:        import org.objectweb.speedo.metadata.SpeedoCommonField;
0040:        import org.objectweb.speedo.metadata.SpeedoDiscriminator;
0041:        import org.objectweb.speedo.metadata.SpeedoElement;
0042:        import org.objectweb.speedo.metadata.SpeedoExtension;
0043:        import org.objectweb.speedo.metadata.SpeedoFetchGroup;
0044:        import org.objectweb.speedo.metadata.SpeedoField;
0045:        import org.objectweb.speedo.metadata.SpeedoIdentity;
0046:        import org.objectweb.speedo.metadata.SpeedoIndex;
0047:        import org.objectweb.speedo.metadata.SpeedoInheritance;
0048:        import org.objectweb.speedo.metadata.SpeedoInheritedField;
0049:        import org.objectweb.speedo.metadata.SpeedoJoin;
0050:        import org.objectweb.speedo.metadata.SpeedoJoinColumn;
0051:        import org.objectweb.speedo.metadata.SpeedoMap;
0052:        import org.objectweb.speedo.metadata.SpeedoNoFieldColumn;
0053:        import org.objectweb.speedo.metadata.SpeedoNullValue;
0054:        import org.objectweb.speedo.metadata.SpeedoPackage;
0055:        import org.objectweb.speedo.metadata.SpeedoPredefinedQuery;
0056:        import org.objectweb.speedo.metadata.SpeedoTable;
0057:        import org.objectweb.speedo.metadata.SpeedoVersion;
0058:        import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
0059:        import org.objectweb.speedo.sequence.jdo.JDOSequence;
0060:        import org.objectweb.speedo.sequence.lib.SpeedoSequence;
0061:        import org.objectweb.util.monolog.api.BasicLevel;
0062:        import org.objectweb.util.monolog.api.Logger;
0063:        import org.w3c.dom.Node;
0064:        import org.w3c.dom.NodeList;
0065:
0066:        /**
0067:         * This class is a parser of the JDO2 persistent descriptor. It includes the 
0068:         * parsing the O/R mapping.
0069:         * 
0070:         * @author S.Chassande-Barrioz
0071:         */
0072:        public class JDO2Parser extends AbstractParser {
0073:
0074:            public JDO2Parser() {
0075:                super (Personality.JDO);
0076:            }
0077:
0078:            public void process() throws SpeedoException {
0079:                super .process();
0080:                //compute fields number for each class
0081:                for (Iterator itDesc = scp.getXmldescriptor().values()
0082:                        .iterator(); itDesc.hasNext();) {
0083:                    SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc
0084:                            .next();
0085:                    for (Iterator itPack = desc.packages.values().iterator(); itPack
0086:                            .hasNext();) {
0087:                        SpeedoPackage sp = (SpeedoPackage) itPack.next();
0088:                        for (Iterator itclass = sp.classes.values().iterator(); itclass
0089:                                .hasNext();) {
0090:                            SpeedoClass clazz = (SpeedoClass) itclass.next();
0091:                            clazz.computeFieldNumbers();
0092:                        }
0093:                    }
0094:                }
0095:            }
0096:
0097:            protected String getLoggerName() {
0098:                return "jdo2";
0099:            }
0100:
0101:            protected Object treatDocument(Node node, Object mo)
0102:                    throws SpeedoException {
0103:                SpeedoXMLDescriptor xmlDesc = (SpeedoXMLDescriptor) mo;
0104:                Map docChildren = groupChildrenByName(node);
0105:                List l = (List) docChildren.remove("jdo");
0106:                if (l != null) {
0107:                    for (int i = 0; i < l.size(); i++) {
0108:                        treatJdoNode((Node) l.get(i), xmlDesc);
0109:                    }
0110:                }
0111:                return mo;
0112:            }
0113:
0114:            protected Object treatJdoNode(Node jdoNode,
0115:                    SpeedoXMLDescriptor xmlDesc) throws SpeedoException {
0116:                Map jdoChildren = groupChildrenByName(jdoNode);
0117:                List packages = (List) jdoChildren.remove("package");
0118:                if (packages != null) {
0119:                    for (int i = 0; i < packages.size(); i++) {
0120:                        Node packageNode = (Node) packages.get(i);
0121:                        Node n = packageNode.getAttributes().getNamedItem(
0122:                                "name");
0123:                        if (n == null) {
0124:                            logger
0125:                                    .log(BasicLevel.ERROR,
0126:                                            "Attribute 'name' for tag package required.");
0127:                            continue;
0128:                        }
0129:                        SpeedoPackage p = new SpeedoPackage();
0130:                        p.name = n.getNodeValue();
0131:                        xmlDesc.add(p, true, logger);
0132:                        logger.log(BasicLevel.DEBUG, "Parsing package: name= "
0133:                                + p.name);
0134:                        Map packageChildren = groupChildrenByName(packageNode);
0135:                        treatExtensions((List) packageChildren
0136:                                .remove("extension"), p);
0137:                        List l = (List) packageChildren.remove("sequence");
0138:                        if (l != null) {
0139:                            for (int j = 0; j < l.size(); j++) {
0140:                                Node classNode = (Node) l.get(j);
0141:                                treatSequenceNode(classNode, p);
0142:                            }
0143:                        }
0144:                        l = (List) packageChildren.remove("class");
0145:                        if (l != null) {
0146:                            for (int j = 0; j < l.size(); j++) {
0147:                                Node classNode = (Node) l.get(j);
0148:                                treatClassNode(classNode, p);
0149:                            }
0150:                        }
0151:                    }
0152:                }
0153:                List queries = (List) jdoChildren.remove("query");
0154:                if (queries != null) {
0155:                    xmlDesc.queries = new ArrayList(queries.size());
0156:                    for (int i = 0; i < queries.size(); i++) {
0157:                        SpeedoPredefinedQuery spq = getQuery((Node) queries
0158:                                .get(i));
0159:                        xmlDesc.queries.add(spq);
0160:                    }
0161:                }
0162:                return xmlDesc;
0163:            }
0164:
0165:            private Map groupChildrenByName(Node n) {
0166:                NodeList nl = n.getChildNodes();
0167:                int size = nl.getLength();
0168:                if (size == 0) {
0169:                    return Collections.EMPTY_MAP;
0170:                }
0171:                HashMap result = new HashMap(size);
0172:                for (int i = 0; i < size; i++) {
0173:                    Node child = nl.item(i);
0174:                    String name = child.getNodeName();
0175:                    List l = (List) result.get(name);
0176:                    if (l == null) {
0177:                        l = new ArrayList();
0178:                        result.put(name, l);
0179:                    }
0180:                    l.add(child);
0181:                }
0182:                return result;
0183:            }
0184:
0185:            private void unmanaged(Node node, Map unmanagedChildren) {
0186:                if (unmanagedChildren != null && unmanagedChildren.size() > 0) {
0187:                    logger.log(BasicLevel.WARN, "Umanaged sub node of "
0188:                            + node.getNodeName() + ": "
0189:                            + unmanagedChildren.keySet());
0190:                }
0191:            }
0192:
0193:            private void treatSequenceNode(Node seqNode, SpeedoPackage p)
0194:                    throws SpeedoException {
0195:                SpeedoSequence s = new JDOSequence();
0196:                Node n = null;
0197:
0198:                //<!ATTLIST sequence name CDATA #REQUIRED>
0199:                n = seqNode.getAttributes().getNamedItem("name");
0200:                if (n == null)
0201:                    throw new SpeedoXMLError(
0202:                            "Attribute name for tag sequence requested.");
0203:                s.name = n.getNodeValue();
0204:                p.addSequence(s);
0205:
0206:                //<!ATTLIST sequence datastore-sequence CDATA #IMPLIED>
0207:                n = seqNode.getAttributes().getNamedItem("datastore-sequence");
0208:                if (n != null)
0209:                    s.datastoreName = n.getNodeValue();
0210:
0211:                //<!ATTLIST sequence factory-class CDATA #IMPLIED>
0212:                n = seqNode.getAttributes().getNamedItem("factory-class");
0213:                if (n != null) {
0214:                    s.factoryClass = n.getNodeValue();
0215:                }
0216:
0217:                //<!ATTLIST sequence strategy (nontransactional|contiguous|noncontiguous) #REQUIRED>
0218:                n = seqNode.getAttributes().getNamedItem("strategy");
0219:                if (n == null) {
0220:                    throw new SpeedoXMLError(
0221:                            "Attribute strategy for tag sequence requested.");
0222:                }
0223:                s.strategy = SpeedoSequence.strategyToByte(n.getNodeValue());
0224:
0225:                //<!ELEMENT sequence (extension*)>
0226:                Map seqChildren = groupChildrenByName(seqNode);
0227:                treatExtensions((List) seqChildren.get("extension"), p);
0228:
0229:                if (debug) {
0230:                    logger.log(BasicLevel.DEBUG, "New sequence: " + "name="
0231:                            + s.name + "  / datastoreName = " + s.datastoreName
0232:                            + "  / factoryClass = " + s.factoryClass
0233:                            + "  / strategy = " + s.strategy);
0234:                }
0235:            }
0236:
0237:            private void treatIndexNode(Node indexNode, SpeedoClass sc)
0238:                    throws SpeedoException {
0239:                SpeedoIndex si = new SpeedoIndex();
0240:                Node n = null;
0241:
0242:                //attribut name (compulsory)
0243:                n = indexNode.getAttributes().getNamedItem("name");
0244:                if (n == null)
0245:                    throw new SpeedoXMLError(
0246:                            "Attribute name for tag index requested.");
0247:                si.name = n.getNodeValue();
0248:
0249:                //attribute unique
0250:                n = indexNode.getAttributes().getNamedItem("unique");
0251:                if (n != null)
0252:                    si.unique = Boolean.valueOf(n.getNodeValue())
0253:                            .booleanValue();
0254:
0255:                //attribute table (compulsory)
0256:                n = indexNode.getAttributes().getNamedItem("table");
0257:                if (n == null)
0258:                    throw new SpeedoXMLError(
0259:                            "Attribute table for tag index requested.");
0260:                si.table = n.getNodeValue();
0261:
0262:                //add the SpeedoIndex to the SpeedoTable
0263:                boolean linked = false;
0264:                //test the main table
0265:                if (sc.mainTable != null) {
0266:                    if (sc.mainTable.name.equals(si.table)) {
0267:                        sc.mainTable.indexes.add(si);
0268:                        linked = true;
0269:                    }
0270:                }
0271:                //and if no success with the main table try the joined tables
0272:                if (!linked && sc.joinToExtTables != null) {
0273:                    for (int i = 0; i < sc.joinToExtTables.length && !linked; i++) {
0274:                        if (sc.joinToExtTables[i].extTable.name.equals(si.name)) {
0275:                            sc.joinToExtTables[i].extTable.indexes.add(si);
0276:                            linked = true;
0277:                        }
0278:                    }
0279:                }
0280:
0281:                Map classChildren = groupChildrenByName(indexNode);
0282:                //extension*, (column|field|property)*
0283:                treatExtensions((List) classChildren.get("extension"), si);
0284:                List l = (List) classChildren.get("field");
0285:                if (l != null) {
0286:                    for (int j = 0; j < l.size(); j++) {
0287:                        treatFieldNode((Node) l.get(j), sc, si);
0288:                    }
0289:                }
0290:                si.speedoClass = sc;
0291:                //      TODO: unmanaged stuff of class
0292:                unmanaged(null, new String[] { "column", "property" },
0293:                        indexNode, classChildren);
0294:            }
0295:
0296:            private void treatClassNode(Node classNode, SpeedoPackage p)
0297:                    throws SpeedoException {
0298:                Node n = null;
0299:                //attribute name (compulsory)
0300:                n = classNode.getAttributes().getNamedItem("name");
0301:                if (n == null) {
0302:                    logger.log(BasicLevel.ERROR,
0303:                            "Attribute 'name' for tag class required.");
0304:                    return;
0305:                }
0306:                SpeedoClass c = new SpeedoClass();
0307:                c.name = n.getNodeValue();
0308:                p.addClass(c, true, logger);
0309:
0310:                //attribute identity-type
0311:                n = classNode.getAttributes().getNamedItem("identity-type");
0312:                if (n != null)
0313:                    c.setIdentityType(SpeedoIdentity.getStrategy(n
0314:                            .getNodeValue()));
0315:
0316:                //attribute object-id
0317:                n = classNode.getAttributes().getNamedItem("objectid-class");
0318:                if (n != null) {
0319:                    c.identity.objectidClass = n.getNodeValue();
0320:                    c.setIdentityType(SpeedoIdentity.USER_ID);
0321:                }
0322:
0323:                //attribute requires-extent is not taken into account
0324:
0325:                //attribute detachable
0326:                n = classNode.getAttributes().getNamedItem("detachable");
0327:                if (n != null)
0328:                    c.isDetachable = Boolean.valueOf(n.getNodeValue())
0329:                            .booleanValue();
0330:
0331:                //attribute persistence-capable-superclass
0332:                n = classNode.getAttributes().getNamedItem(
0333:                        "persistence-capable-superclass");
0334:                if (n != null) {
0335:                    if (c.inheritance == null) {
0336:                        c.inheritance = new SpeedoInheritance(c);
0337:                    }
0338:                    c.inheritance.super ClassName = n.getNodeValue();
0339:                }
0340:                //attribute table
0341:                n = classNode.getAttributes().getNamedItem("table");
0342:                if (n != null) {
0343:                    c.mainTable = new SpeedoTable();
0344:                    c.mainTable.name = n.getNodeValue();
0345:                }
0346:                if (c.mainTable == null) {
0347:                    if (c.inheritance == null
0348:                            || c.inheritance.strategy == SpeedoInheritance.STRATEGY_NEW_TABLE) {
0349:                        c.mainTable = new SpeedoTable();
0350:                        c.mainTable.name = c.name.toUpperCase();
0351:                    }
0352:                }
0353:
0354:                logger.log(BasicLevel.DEBUG, "New class: " + "name=" + c.name
0355:                        + "  / id = " + c.getIdentityType() + "  / idClass = "
0356:                        + c.identity.objectidClass + "  / detachable = "
0357:                        + c.isDetachable);
0358:
0359:                Map classChildren = groupChildrenByName(classNode);
0360:                //extension*, implements*, datastore-identity?, inheritance?, version?, 
0361:                // join*, foreign-key*, index*, unique*, field*, query*, fetch-group*, extension*
0362:                treatExtensions((List) classChildren.get("extension"), c);
0363:                List l = (List) classChildren.get("datastore-identity");
0364:                if (l != null) {
0365:                    treatDataStoreId((Node) l.get(0), c);
0366:                }
0367:                l = (List) classChildren.get("inheritance");
0368:                if (l != null) {
0369:                    treatInheritance((Node) l.get(0), c);
0370:                }
0371:                l = (List) classChildren.get("version");
0372:                if (l != null) {
0373:                    treatVersion((Node) l.get(0), c);
0374:                }
0375:                l = (List) classChildren.get("join");
0376:                if (l != null) {
0377:                    for (int j = 0; j < l.size(); j++) {
0378:                        Object[] os = getJoin((Node) l.get(j), null);
0379:                        SpeedoJoin join = (SpeedoJoin) os[0];
0380:                        String tableName = (String) os[1];
0381:                        //define an external/secondary table
0382:                        c.addJoin(join);
0383:                        if (c.mainTable != null) {
0384:                            join.mainTable = c.mainTable;
0385:                        }
0386:                        if (tableName != null) {
0387:                            join.extTable = new SpeedoTable();
0388:                            join.extTable.name = tableName;
0389:                            join.extTable.join = join;
0390:                        }
0391:                    }
0392:                }
0393:                l = (List) classChildren.get("field");
0394:                if (l != null) {
0395:                    for (int j = 0; j < l.size(); j++) {
0396:                        treatFieldNode((Node) l.get(j), c);
0397:                    }
0398:                }
0399:                l = (List) classChildren.get("query");
0400:                if (l != null) {
0401:                    for (int j = 0; j < l.size(); j++) {
0402:                        SpeedoPredefinedQuery spq = getQuery((Node) l.get(j));
0403:                        c.name2query.put(spq.name, spq);
0404:                    }
0405:                }
0406:                l = (List) classChildren.get("index");
0407:                if (l != null) {
0408:                    for (int j = 0; j < l.size(); j++) {
0409:                        treatIndexNode((Node) l.get(j), c);
0410:                    }
0411:                }
0412:                l = (List) classChildren.get("fetch-group");
0413:                if (l != null) {
0414:                    for (int j = 0; j < l.size(); j++) {
0415:                        treatFetchGroupNode((Node) l.get(j), c);
0416:                    }
0417:                }
0418:
0419:                //TODO: unmanaged stuff of class
0420:                unmanaged(null, new String[] { "foreign-key", "unique" },
0421:                        classNode, classChildren);
0422:            }
0423:
0424:            private void treatDataStoreId(Node dsiNode, SpeedoClass moClass)
0425:                    throws SpeedoException {
0426:                SpeedoIdentity ident = new SpeedoIdentity(); //default strategy is native
0427:                //<!ATTLIST datastore-identity strategy CDATA 'native'>
0428:                Node n = dsiNode.getAttributes().getNamedItem("strategy");
0429:                if (n == null)
0430:                    throw new SpeedoXMLError(
0431:                            "Attribute strategy for tag datastore-identity requested.");
0432:                ident.strategy = SpeedoIdentity.getStrategy(n.getNodeValue());
0433:
0434:                //<!ATTLIST datastore-identity sequence CDATA #IMPLIED>
0435:                n = dsiNode.getAttributes().getNamedItem("sequence");
0436:                if (n != null)
0437:                    ident.sequenceName = n.getNodeValue();
0438:
0439:                //<!ATTLIST datastore-identity column CDATA #IMPLIED>
0440:                List columns = null;
0441:                n = dsiNode.getAttributes().getNamedItem("column");
0442:                if (n != null) {
0443:                    columns = new ArrayList();
0444:                    columns.add(new SpeedoColumn(n.getNodeValue()));
0445:
0446:                }
0447:                //<!ELEMENT datastore-identity (extension*, column*, extension*)>
0448:                //inner element column
0449:                Map dsiChildren = groupChildrenByName(dsiNode);
0450:                treatExtensions((List) dsiChildren.get("extension"), ident);
0451:                //TODO: unmanaged stuff of class
0452:                unmanaged(null,
0453:                        new String[] { "index", "unique", "fetch-group" },
0454:                        dsiNode, dsiChildren);
0455:                List columnNodes = (List) dsiChildren.get("column");
0456:                if (columnNodes != null) {
0457:                    for (int i = 0; i < columnNodes.size(); i++) {
0458:                        if (columns == null) {
0459:                            columns = new ArrayList();
0460:                        }
0461:                        Node columnNode = (Node) columnNodes.get(i);
0462:                        columns.add(getColumn(columnNode));
0463:                    }
0464:                }
0465:                if (columns != null) {
0466:                    moClass.identity.setColumns(columns);
0467:                }
0468:                //bind the identity to the moClass
0469:                moClass.identity = ident;
0470:                if (debug) {
0471:                    logger.log(BasicLevel.DEBUG, "New datastore-identity: "
0472:                            + "identity=" + ident);
0473:                }
0474:            }
0475:
0476:            private void treatInheritance(Node inhNode, SpeedoClass moClass)
0477:                    throws SpeedoException {
0478:                if (moClass.inheritance == null) {
0479:                    moClass.inheritance = new SpeedoInheritance(moClass);
0480:                }
0481:                //<!ATTLIST inheritance strategy CDATA #IMPLIED>
0482:                Node n = inhNode.getAttributes().getNamedItem("strategy");
0483:                if (n != null) {
0484:                    moClass.inheritance.strategy = SpeedoInheritance
0485:                            .parseStrategy(n.getNodeValue());
0486:                    logger
0487:                            .log(
0488:                                    BasicLevel.DEBUG,
0489:                                    "defines the strategy '"
0490:                                            + SpeedoInheritance
0491:                                                    .strategy2str(moClass.inheritance.strategy));
0492:                }
0493:                //<!ELEMENT inheritance (extension*, join?, discriminator?, extension*)>
0494:                Map inhChildren = groupChildrenByName(inhNode);
0495:                //inner element extension
0496:                treatExtensions((List) inhChildren.get("extension"),
0497:                        moClass.inheritance);
0498:                //inner element join
0499:                List l = (List) inhChildren.get("join");
0500:                if (l != null) {
0501:                    //define a join to the super class (vertical mapping)
0502:                    Object[] os = getJoin((Node) l.get(0), null);
0503:                    moClass.inheritance.join = (SpeedoJoin) os[1];
0504:                }
0505:                //inner element discriminator
0506:                l = (List) inhChildren.get("discriminator");
0507:                if (l != null) {
0508:                    treatDiscriminator((Node) l.get(0), moClass.inheritance);
0509:                }
0510:            }
0511:
0512:            private void treatDiscriminator(Node discNode, SpeedoInheritance inh)
0513:                    throws SpeedoException {
0514:                if (inh.discriminator == null) {
0515:                    inh.discriminator = new SpeedoDiscriminator();
0516:                }
0517:                //<!ATTLIST discriminator strategy CDATA #IMPLIED>
0518:                Node n = discNode.getAttributes().getNamedItem("strategy");
0519:                if (n != null) {
0520:                    inh.discriminator.strategy = SpeedoDiscriminator
0521:                            .parseStrategy(n.getNodeValue());
0522:                }
0523:                //<!ELEMENT discriminator (extension*, column*, index?, extension*)>
0524:                //inner element extension
0525:                Map discChildren = groupChildrenByName(discNode);
0526:
0527:                //<!ATTLIST discriminator value CDATA #IMPLIED>
0528:                n = discNode.getAttributes().getNamedItem("value");
0529:                String val = null;
0530:                if (n != null) {
0531:                    val = n.getNodeValue();
0532:                }
0533:
0534:                //<!ATTLIST discriminator column CDATA #IMPLIED>
0535:                n = discNode.getAttributes().getNamedItem("column");
0536:                SpeedoColumn col = null;
0537:                if (n != null) {
0538:                    col = new SpeedoColumn(n.getNodeValue());
0539:                } else {
0540:                    //inner element column
0541:                    List columnNodes = (List) discChildren.get("column");
0542:                    if (columnNodes != null && columnNodes.size() == 1) {
0543:                        Node columnNode = (Node) columnNodes.get(0);
0544:                        col = getColumn(columnNode);
0545:                    }
0546:                }
0547:                if (col == null) {
0548:                    if (val != null) {
0549:                        //try to use the default column
0550:
0551:                    }
0552:                } else {
0553:                    if (val != null) {
0554:
0555:                    } else {
0556:                        //column definition on abstract class
0557:                    }
0558:                }
0559:                SpeedoNoFieldColumn snfc = new SpeedoNoFieldColumn();
0560:                snfc.column = col;
0561:                inh.discriminator.elements.add(snfc);
0562:                if (val != null) {
0563:                    if (inh.discriminatorValues == null) {
0564:                        inh.discriminatorValues = new HashMap();
0565:                    }
0566:                    inh.discriminator.setDiscriminatorValue(val, inh, snfc);
0567:                }
0568:
0569:                treatExtensions((List) discChildren.get("extension"),
0570:                        inh.discriminator);
0571:                unmanaged(new String[] { "indexed" }, new String[] { "index" },
0572:                        discNode, discChildren);
0573:            }
0574:
0575:            private Object[] getJoin(Node joinNode, SpeedoJoin j)
0576:                    throws SpeedoException {
0577:                Node n = joinNode.getAttributes().getNamedItem("table");
0578:                if (j == null) {
0579:                    j = new SpeedoJoin();
0580:                }
0581:                n = joinNode.getAttributes().getNamedItem("delete-action");
0582:                if (n != null) {
0583:                    String v = n.getNodeValue();
0584:                    if ("restrict".equals(v)) {
0585:                        j.deleteAction = SpeedoJoin.ACTION_RESTRICT;
0586:                    } else if ("cascade".equals(v)) {
0587:                        j.deleteAction = SpeedoJoin.ACTION_CASCADE;
0588:                    } else if ("null".equals(v)) {
0589:                        j.deleteAction = SpeedoJoin.ACTION_NULL;
0590:                    } else if ("none".equals(v)) {
0591:                        j.deleteAction = SpeedoJoin.ACTION_NONE;
0592:                    } else if ("default".equals(v)) {
0593:                        j.deleteAction = SpeedoJoin.ACTION_DEFAULT;
0594:                    } else {
0595:                        j.deleteAction = SpeedoJoin.ACTION_DEFAULT;
0596:                    }
0597:                }
0598:                j.setUnique(getBooleanAttributeValue(joinNode, "unique", j
0599:                        .getUnique()));
0600:                j.setIndexed(getBooleanAttributeValue(joinNode, "indexed", j
0601:                        .getIndexed()));
0602:                j.setOuter(getBooleanAttributeValue(joinNode, "indexed", j
0603:                        .getOuter()));
0604:                n = joinNode.getAttributes().getNamedItem("column");
0605:                if (n != null) {
0606:                    SpeedoJoinColumn sjc = new SpeedoJoinColumn(
0607:                            new SpeedoColumn(n.getNodeValue()));
0608:                    j.columns.add(sjc);
0609:                }
0610:                Map joinChildren = groupChildrenByName(joinNode);
0611:                List l = (List) joinChildren.get("column");
0612:                if (l != null) {
0613:                    for (int i = 0; i < l.size(); i++) {
0614:                        j.columns.add(new SpeedoJoinColumn(getColumn((Node) l
0615:                                .get(i))));
0616:                    }
0617:                }
0618:                n = joinNode.getAttributes().getNamedItem("table");
0619:                String tableName = null;
0620:                if (n != null) {
0621:                    tableName = n.getNodeValue();
0622:                }
0623:                return new Object[] { j, tableName };
0624:            }
0625:
0626:            private void treatVersion(Node versionNode, SpeedoClass moClass)
0627:                    throws SpeedoException {
0628:                SpeedoVersion v = new SpeedoVersion();
0629:                //attribute embedded-element
0630:                //<!ATTLIST version strategy CDATA #IMPLIED>
0631:                Node n = versionNode.getAttributes().getNamedItem("strategy");
0632:                v.strategy = SpeedoVersion.toByte(n.getNodeValue());
0633:
0634:                //<!ATTLIST version indexed (true|false|unique) #IMPLIED>
0635:                n = versionNode.getAttributes().getNamedItem("strategy");
0636:                if (n != null) {
0637:                    //TODO: Speedo does not support yet the indexed attribute in version tag
0638:                    logger
0639:                            .log(BasicLevel.WARN,
0640:                                    "Speedo does not support yet the indexed attribute in version tag");
0641:                }
0642:
0643:                //<!ATTLIST version column CDATA #IMPLIED>
0644:                List columns = null;
0645:                n = versionNode.getAttributes().getNamedItem("column");
0646:                if (n != null) {
0647:                    columns = new ArrayList();
0648:                    columns.add(new SpeedoColumn(n.getNodeValue()));
0649:                }
0650:                //<!ELEMENT version (extension*, column*, index?, extension*)>
0651:                Map versionChildren = groupChildrenByName(versionNode);
0652:                unmanaged(new String[] { "column" }, new String[] { "column",
0653:                        "index" }, versionNode, versionChildren);
0654:                moClass.version = v;
0655:                logger.log(BasicLevel.DEBUG, "New version: strategy="
0656:                        + v.strategy);
0657:            }
0658:
0659:            private void treatExtensions(List nodes, SpeedoElement se)
0660:                    throws SpeedoException {
0661:                if (nodes != null) {
0662:                    for (int i = 0; i < nodes.size(); i++) {
0663:                        treatExtension((Node) nodes.get(i), se);
0664:                    }
0665:                }
0666:            }
0667:
0668:            private void treatExtension(Node node, SpeedoElement se)
0669:                    throws SpeedoException {
0670:                SpeedoExtension e = new SpeedoExtension();
0671:                //<!ATTLIST extension vendor-name CDATA #REQUIRED>
0672:                Node n = node.getAttributes().getNamedItem("vendor-name");
0673:                e.vendorName = n.getNodeValue();
0674:                //<!ATTLIST extension key CDATA #IMPLIED>
0675:                n = node.getAttributes().getNamedItem("key");
0676:                if (n != null) {
0677:                    e.key = n.getNodeValue();
0678:                }
0679:                //<!ATTLIST extension value CDATA #IMPLIED>
0680:                n = node.getAttributes().getNamedItem("value");
0681:                if (n != null) {
0682:                    e.value = n.getNodeValue();
0683:                }
0684:                //<!ELEMENT extension ANY>
0685:
0686:                logger.log(BasicLevel.DEBUG, "Parse extension name=" + e.key
0687:                        + ", value=" + e.value);
0688:                se.addExtension(e);
0689:                e.owner = se;
0690:            }
0691:
0692:            private SpeedoColumn getColumn(Node node) throws SpeedoException {
0693:                SpeedoColumn c = new SpeedoColumn();
0694:                Node n = node.getAttributes().getNamedItem("name");
0695:                if (n != null) {
0696:                    c.name = n.getNodeValue();
0697:                }
0698:                n = node.getAttributes().getNamedItem("target");
0699:                if (n != null) {
0700:                    c.targetColumn = n.getNodeValue();
0701:                }
0702:                n = node.getAttributes().getNamedItem("target-field");
0703:                if (n != null) {
0704:                    c.targetField = n.getNodeValue();
0705:                }
0706:                n = node.getAttributes().getNamedItem("jdbc-type");
0707:                if (n != null) {
0708:                    c.jdbcType = n.getNodeValue();
0709:                }
0710:                n = node.getAttributes().getNamedItem("sql-type");
0711:                if (n != null) {
0712:                    c.sqlType = n.getNodeValue();
0713:                }
0714:                n = node.getAttributes().getNamedItem("length");
0715:                if (n != null) {
0716:                    c.length = Integer.parseInt(n.getNodeValue());
0717:                }
0718:                n = node.getAttributes().getNamedItem("scale");
0719:                if (n != null) {
0720:                    c.scale = Integer.parseInt(n.getNodeValue());
0721:                }
0722:                c.allowNull = getBooleanAttributeValue(node, "allows-null",
0723:                        c.allowNull);
0724:                n = node.getAttributes().getNamedItem("default-value");
0725:                if (n != null) {
0726:                    c.defaultValue = n.getNodeValue();
0727:                }
0728:                return c;
0729:            }
0730:
0731:            private SpeedoPredefinedQuery getQuery(Node queryNode)
0732:                    throws SpeedoException {
0733:                //TODO: verify DTD about query
0734:                SpeedoPredefinedQuery spq = new SpeedoPredefinedQuery();
0735:                //<!ATTLIST query name CDATA #IMPLIED>
0736:                spq.name = getStringAttributeValue(queryNode, "name", null);
0737:                //<!ATTLIST query language CDATA #IMPLIED>
0738:                spq.language = getStringAttributeValue(queryNode, "language",
0739:                        null);
0740:                //<!ELEMENT query (#PCDATA|extension)*>
0741:                spq.query = queryNode.getNodeValue();
0742:                Map queryChildren = groupChildrenByName(queryNode);
0743:                treatExtensions((List) queryChildren.get("extension"), spq);
0744:                return spq;
0745:            }
0746:
0747:            private SpeedoFetchGroup getFetchGroup(Node fgNode,
0748:                    SpeedoClass fieldOwner) throws SpeedoException {
0749:                SpeedoFetchGroup fg = new SpeedoFetchGroup();
0750:                //<!ATTLIST fetch-group name CDATA #REQUIRED>
0751:                Node n = fgNode.getAttributes().getNamedItem("name");
0752:                fg.name = n.getNodeValue();
0753:
0754:                //<!ATTLIST fetch-group post-load (true|false) #IMPLIED>
0755:                n = fgNode.getAttributes().getNamedItem("post-load");
0756:                if (n != null) {
0757:                    fg.postLoad = Boolean.valueOf(n.getNodeValue())
0758:                            .booleanValue();
0759:                } else {
0760:                    if (fg.name.equals("default")) {
0761:                        fg.postLoad = true;
0762:                    } else {
0763:                        fg.postLoad = false;
0764:                    }
0765:                }
0766:                Map fgChildren = groupChildrenByName(fgNode);
0767:                //<!ELEMENT fetch-group (fetch-group|field)*>
0768:                List l = (List) fgChildren.get("field");
0769:                if (l != null) {
0770:                    for (int j = 0; j < l.size(); j++) {
0771:                        Node fieldNode = (Node) l.get(j);
0772:                        String fieldName = getStringAttributeValue(fieldNode,
0773:                                "name", null);
0774:                        if (fieldName != null) {
0775:                            SpeedoField field = fieldOwner.getField(fieldName);
0776:                            if (field != null) {
0777:                                fg.addField(field);
0778:                            } else {
0779:                                logger.log(BasicLevel.WARN, "Bad field name '"
0780:                                        + fieldName + "'in the fetch group '"
0781:                                        + fg.name + "' in the class "
0782:                                        + fieldOwner.getSourceDesc() + ".");
0783:                            }
0784:                        }
0785:                    }
0786:                }
0787:                l = (List) fgChildren.get("fetch-group");
0788:                if (l != null) {
0789:                    for (int j = 0; j < l.size(); j++) {
0790:                        SpeedoFetchGroup subfg = getFetchGroup((Node) l.get(j),
0791:                                fieldOwner);
0792:                        if (logger.isLoggable(BasicLevel.DEBUG)) {
0793:                            logger.log(BasicLevel.DEBUG, "add fetchgroup '"
0794:                                    + subfg.name + "' into the fetchgroup '"
0795:                                    + fg.name + "'");
0796:                        }
0797:                        fg.addFetchGroup(subfg);
0798:                    }
0799:                }
0800:                return fg;
0801:            }
0802:
0803:            private void treatFieldNode(Node fieldNode, SpeedoClass moClass,
0804:                    SpeedoIndex moIndex) throws SpeedoException {
0805:                //at the moment, only support for field with name attribute
0806:                //no support for field definition within the index tag 
0807:                Node n = null;
0808:
0809:                //<!ATTLIST field name CDATA #REQUIRED>
0810:                n = fieldNode.getAttributes().getNamedItem("name");
0811:                if (n == null)
0812:                    throw new SpeedoXMLError(
0813:                            "Attribute name for tag field requested.");
0814:                String name = n.getNodeValue();
0815:                //add the field name to the index
0816:                moIndex.fieldNames.add(name);
0817:                //try to add the column name(s) to the index
0818:                SpeedoField sf = (SpeedoField) moClass.fields.get(name);
0819:                if (sf == null)
0820:                    throw new SpeedoXMLError("The field " + name
0821:                            + " must be defined for the class " + moClass.name
0822:                            + ".");
0823:                if (sf.columns != null && sf.columns.length != 0) {
0824:                    for (int i = 0; i < sf.columns.length; i++) {
0825:                        moIndex.columnNames.add(sf.columns[i].name);
0826:                    }
0827:                } else {
0828:                    logger.log(BasicLevel.WARN, "The column(s) for the field "
0829:                            + name + " has not been defined yet.");
0830:                }
0831:            }
0832:
0833:            private void treatFieldNode(Node fieldNode, SpeedoClass moClass)
0834:                    throws SpeedoException {
0835:                Node n = null;
0836:
0837:                //<!ATTLIST field name CDATA #REQUIRED>
0838:                n = fieldNode.getAttributes().getNamedItem("name");
0839:                if (n == null)
0840:                    throw new SpeedoXMLError(
0841:                            "Attribute name for tag field requested.");
0842:                String name = n.getNodeValue();
0843:                int dotIdx = name.lastIndexOf(".");
0844:                SpeedoField f = null;
0845:                SpeedoCommonField cf;
0846:                FieldContext fc = new FieldContext();
0847:                fc.fieldNode = fieldNode;
0848:                if (dotIdx != -1) {
0849:                    cf = moClass.inheritance.newSpeedoInheritedField(name);
0850:                } else {
0851:                    f = new SpeedoField();
0852:                    cf = f;
0853:                    f.name = n.getNodeValue();
0854:                    f.moClass = moClass;
0855:
0856:                    //<!ATTLIST field persistence-modifier (persistent|transactional|none) #IMPLIED>
0857:                    n = fieldNode.getAttributes().getNamedItem(
0858:                            "persistence-modifier");
0859:                    if (n != null)
0860:                        f.persistenceStatus = SpeedoField
0861:                                .parsePersistenceStatus(n.getNodeValue());
0862:
0863:                    //<!ATTLIST field primary-key (true|false) 'false'>
0864:                    n = fieldNode.getAttributes().getNamedItem("primary-key");
0865:                    if (n != null)
0866:                        f.primaryKey = Boolean.valueOf(n.getNodeValue())
0867:                                .booleanValue();
0868:
0869:                    //<!ATTLIST field null-value (exception|default|none) 'none'>
0870:                    n = fieldNode.getAttributes().getNamedItem("null-value");
0871:                    if (n != null) {
0872:                        f.nullValue = SpeedoNullValue.toByte(n.getNodeValue());
0873:                    }
0874:
0875:                    //<!ATTLIST field default-fetch-group (true|false) #IMPLIED>
0876:                    n = fieldNode.getAttributes().getNamedItem(
0877:                            "default-fetch-group");
0878:                    if (n != null)
0879:                        f.defaultFetchGroup = Boolean.valueOf(n.getNodeValue())
0880:                                .booleanValue();
0881:
0882:                    //attribute fetch-group
0883:                    n = fieldNode.getAttributes().getNamedItem("fetch-group");
0884:                    if (n != null)
0885:                        f.fetchGroup = n.getNodeValue();
0886:
0887:                    //<!ATTLIST field fetch-depth CDATA #IMPLIED>
0888:                    n = fieldNode.getAttributes().getNamedItem("fetch-depth");
0889:                    if (n == null) {
0890:                        n = fieldNode.getAttributes().getNamedItem("depth");
0891:                        if (n != null) {
0892:                            logger
0893:                                    .log(BasicLevel.WARN,
0894:                                            "attribute 'depth' is deprecated, use 'fetch-depth'.");
0895:                        }
0896:                    }
0897:                    if (n != null) {
0898:                        f.depth = Integer.valueOf(n.getNodeValue()).intValue();
0899:                    }
0900:
0901:                    //<!ATTLIST field embedded (true|false) #IMPLIED>
0902:                    n = fieldNode.getAttributes().getNamedItem("embedded");
0903:                    if (n != null)
0904:                        f.embedded = Boolean.valueOf(n.getNodeValue())
0905:                                .booleanValue();
0906:
0907:                    //<!ATTLIST field value-strategy CDATA #IMPLIED>
0908:                    n = fieldNode.getAttributes()
0909:                            .getNamedItem("value-strategy");
0910:                    if (n != null)
0911:                        f.valueStrategy = n.getNodeValue();
0912:
0913:                    //<!ATTLIST field sequence CDATA #IMPLIED>
0914:                    n = fieldNode.getAttributes().getNamedItem("sequence");
0915:                    if (n != null)
0916:                        f.sequence = n.getNodeValue();
0917:
0918:                    //<!ATTLIST field mapped-by CDATA #IMPLIED>
0919:                    n = fieldNode.getAttributes().getNamedItem("mapped-by");
0920:                    if (n != null) {
0921:                        f.reverseField = n.getNodeValue();
0922:                        f.mappedByReversefield = true;
0923:                        f.isCoherentReverseField = true;
0924:                        if (logger.isLoggable(BasicLevel.DEBUG)) {
0925:                            logger.log(BasicLevel.DEBUG, "The field " + f.name
0926:                                    + " is mapped by " + f.reverseField);
0927:                        }
0928:                    }
0929:                }
0930:                fc.field = cf;
0931:
0932:                //<!ATTLIST field table CDATA #IMPLIED>
0933:                fc.parseTableAttribute(fieldNode, logger);
0934:
0935:                //<!ELEMENT field (extension*, (array|collection|map)?, join?, 
0936:                //embedded?, element?, key?, value?, order?, column*, foreign-key?, 
0937:                //index?, unique?, extension*)>
0938:
0939:                fc.fieldChildren = groupChildrenByName(fieldNode);
0940:                List l;
0941:                treatExtensions((List) fc.fieldChildren.get("extension"), cf);
0942:
0943:                if (fc.parseORM()) {
0944:                    //Parse the O/R mapping of the [inherited] field
0945:                    l = (List) fc.fieldChildren.get("join");
0946:                    if (l != null) {
0947:                        //define an external/secondary table used by a particular field
0948:                        Object[] os = getJoin((Node) l.get(0), fc.join);
0949:                        fc.join = (SpeedoJoin) os[0];
0950:                        if (f != null) {
0951:                            logger.log(BasicLevel.DEBUG, "Specify the join "
0952:                                    + fc.join + " to the field " + f.name);
0953:                        } else if (logger.isLoggable(BasicLevel.DEBUG)) {
0954:                            logger.log(BasicLevel.DEBUG, "Specify the join "
0955:                                    + fc.join + " to the inherited field "
0956:                                    + cf.name);
0957:                        }
0958:                    }
0959:                    //<!ATTLIST field column CDATA #IMPLIED>
0960:                    n = fieldNode.getAttributes().getNamedItem("column");
0961:                    if (n != null) {
0962:                        fc.addColumn(new SpeedoColumn(n.getNodeValue()));
0963:                    }
0964:                    l = (List) fc.fieldChildren.get("column");
0965:                    if (l != null) {
0966:                        for (int i = 0; i < l.size(); i++) {
0967:                            fc.addColumn(getColumn((Node) l.get(i)));
0968:                        }
0969:                    }
0970:                }
0971:                boolean isCollection = fc.fieldChildren.get("collection") != null
0972:                        || fc.fieldChildren.get("element") != null;
0973:                boolean isMap = fc.fieldChildren.get("map") != null
0974:                        || fc.fieldChildren.get("key") != null
0975:                        || fc.fieldChildren.get("value") != null;
0976:                boolean isArray = fc.fieldChildren.get("array") != null;
0977:                if (isMap) {
0978:                    if (isCollection) {
0979:                        logger.log(BasicLevel.WARN, "The '" + f.name
0980:                                + "' from the class '" + moClass.getFQName()
0981:                                + "' cannot be a map AND a collection !");
0982:                    }
0983:                }
0984:                if (isCollection) {
0985:                    treatCollectionField(fc);
0986:                } else if (isMap) {
0987:                    treatMapField(fc);
0988:                } else if (isArray) {
0989:
0990:                } else {
0991:                    treatSimpleField(fc);
0992:                }
0993:                unmanaged(new String[] { "serialized", "dependent",
0994:                        "delete-action", "load-fetch-group", "foreign-key",
0995:                        "indexed", "unique" }, new String[] { "embedded",
0996:                        "order", "foreign-key", "unique", "index", "array" },
0997:                        fieldNode, fc.fieldChildren);
0998:                if (f != null) {
0999:                    if (debug) {
1000:                        logger.log(BasicLevel.DEBUG, "New field: " + "name="
1001:                                + f.name + "  / persistenceModifier = "
1002:                                + f.persistenceStatus + "  / primaryKey = "
1003:                                + f.primaryKey + "  / nullValue = "
1004:                                + f.nullValue + "  / defaultFetchGroup = "
1005:                                + f.defaultFetchGroup + "  / embedded = "
1006:                                + f.embedded + "  / depth = " + f.depth
1007:                                + "  / valueStrategy = " + f.valueStrategy
1008:                                + "  / sequence = " + f.sequence);
1009:                    }
1010:                    moClass.add(f, true, logger);
1011:                } //else it is an inherited field already attached to moClass.inheritance
1012:            }
1013:
1014:            private void treatMapField(FieldContext fc) throws SpeedoException {
1015:                SpeedoMap m = (SpeedoMap) fc.field.jdoTuple;
1016:                if (m == null) {
1017:                    m = new SpeedoMap();
1018:                }
1019:                fc.field.jdoTuple = m;
1020:                m.moField = (SpeedoField) fc.field;
1021:                List l = (List) fc.fieldChildren.get("map");
1022:                if (l != null) {
1023:                    l = (List) fc.fieldChildren.get("map");
1024:                    Node mapNode = (Node) l.get(0);
1025:                    //attribut key-type
1026:                    Node n = mapNode.getAttributes().getNamedItem("key-type");
1027:                    if (n != null)
1028:                        m.keyType = n.getNodeValue();
1029:                    //attribut embedded-key
1030:                    n = mapNode.getAttributes().getNamedItem("embedded-key");
1031:                    if (n != null)
1032:                        m.embeddedKey = Boolean.valueOf(n.getNodeValue())
1033:                                .booleanValue();
1034:                    //attribute value-type
1035:                    n = mapNode.getAttributes().getNamedItem("value-type");
1036:                    if (n != null)
1037:                        m.valueType = n.getNodeValue();
1038:                    //attribute embedded-value
1039:                    n = mapNode.getAttributes().getNamedItem("embedded-value");
1040:                    if (n != null)
1041:                        m.embeddedValue = Boolean.valueOf(n.getNodeValue())
1042:                                .booleanValue();
1043:                }
1044:
1045:                l = (List) fc.fieldChildren.get("key");
1046:                if (l != null) {
1047:                    //<!ELEMENT key (extension*, embedded?, column*, foreign-key?, index?, unique?, extension*)>
1048:                    //<!ATTLIST key table CDATA #IMPLIED>
1049:                    //<!ATTLIST key serialized (true|false) #IMPLIED>
1050:                    //<!ATTLIST key delete-action (restrict|cascade|null|default|none) #IMPLIED>
1051:                    //<!ATTLIST key indexed (true|false|unique) #IMPLIED>
1052:                    //<!ATTLIST key unique (true|false) #IMPLIED>
1053:                    Node keyNode = (Node) l.get(0);
1054:                    Map keyChildren = groupChildrenByName(keyNode);
1055:                    if (fc.parseORM()) {
1056:                        //<!ATTLIST key column CDATA #IMPLIED>
1057:                        Node n = keyNode.getAttributes().getNamedItem("column");
1058:                        if (n != null) {
1059:                            SpeedoColumn col = new SpeedoColumn(n
1060:                                    .getNodeValue());
1061:                            //in the same table than map value
1062:                            if (fc.field.columns != null
1063:                                    && fc.field.columns.length > 0) {
1064:                                col.table = fc.field.columns[0].table;
1065:                            }
1066:                            m.keyColumns = col;
1067:                        }
1068:                        l = (List) keyChildren.get("column");
1069:                        if (l != null) {
1070:                            m.keyColumns = getColumn((Node) l.get(0));
1071:                        }
1072:                        fc.parseTableAttribute(keyNode, logger);
1073:                    }
1074:                    unmanaged(new String[] { "serialized", "delete-action",
1075:                            "indexed", "unique" }, new String[] { "embedded",
1076:                            "foreign-key", "unique", "index" }, keyNode,
1077:                            keyChildren);
1078:                }
1079:                l = (List) fc.fieldChildren.get("value");
1080:                if (l != null) {
1081:                    //<!ELEMENT value (extension*, embedded?, column*, foreign-key?, index?, unique?, extension*)>
1082:                    //<!ATTLIST value serialized (true|false) #IMPLIED>
1083:                    //<!ATTLIST value table CDATA #IMPLIED>
1084:                    //<!ATTLIST value delete-action (restrict|cascade|null|default|none) #IMPLIED>
1085:                    //<!ATTLIST value indexed (true|false|unique) #IMPLIED>
1086:                    //<!ATTLIST value unique (true|false) #IMPLIED>
1087:                    Node valueNode = (Node) l.get(0);
1088:                    Map valueChildren = groupChildrenByName(valueNode);
1089:                    if (fc.parseORM()) {
1090:                        //<!ATTLIST value column CDATA #IMPLIED>
1091:                        Node n = valueNode.getAttributes().getNamedItem(
1092:                                "column");
1093:                        if (n != null) {
1094:                            fc.addColumn(new SpeedoColumn(n.getNodeValue()));
1095:                        }
1096:                        l = (List) valueChildren.get("column");
1097:                        if (l != null) {
1098:                            for (int i = 0; i < l.size(); i++) {
1099:                                fc.addColumn(getColumn((Node) l.get(i)));
1100:                            }
1101:                        }
1102:                        fc.parseTableAttribute(valueNode, logger);
1103:                    }
1104:                    unmanaged(new String[] { "serialized", "delete-action",
1105:                            "indexed", "unique" }, new String[] { "embedded",
1106:                            "foreign-key", "unique", "index" }, valueNode,
1107:                            valueChildren);
1108:                }
1109:                if (fc.join != null && fc.field.moClass.containsJoin(fc.join)) {
1110:                    fc.field.moClass.removeJoin(fc.join);
1111:                }
1112:                logger.log(BasicLevel.DEBUG, "New map: " + "keyType="
1113:                        + m.keyType + "  / embeddedKey = " + m.embeddedKey
1114:                        + "  / valueType = " + m.valueType
1115:                        + "  / embeddedValue = " + m.embeddedValue);
1116:            }
1117:
1118:            private void treatCollectionField(FieldContext fc)
1119:                    throws SpeedoException {
1120:                List l = (List) fc.fieldChildren.get("collection");
1121:                if (l != null) {
1122:                    Node collectionNode = (Node) l.get(0);
1123:                    SpeedoCollection co = (SpeedoCollection) fc.field.jdoTuple;
1124:                    if (co == null) {
1125:                        co = new SpeedoCollection();
1126:                    }
1127:                    fc.field.jdoTuple = co;
1128:                    co.moField = (SpeedoField) fc.field;
1129:                    //attribute element-type
1130:                    Node n = collectionNode.getAttributes().getNamedItem(
1131:                            "element-type");
1132:                    if (n != null)
1133:                        co.elementType = n.getNodeValue();
1134:
1135:                    //attribute embedded-element
1136:                    n = collectionNode.getAttributes().getNamedItem(
1137:                            "embedded-element");
1138:                    if (n != null) {
1139:                        co.embeddedElement = Boolean.valueOf(n.getNodeValue())
1140:                                .booleanValue();
1141:                    }
1142:                    if (debug) {
1143:                        logger
1144:                                .log(BasicLevel.DEBUG, "New collection: "
1145:                                        + "elementType=" + co.elementType
1146:                                        + "  / embeddedElement = "
1147:                                        + co.embeddedElement);
1148:                    }
1149:                }
1150:                l = (List) fc.fieldChildren.get("element");
1151:                if (l != null) {
1152:                    //<!ATTLIST element column CDATA #IMPLIED>
1153:                    Node elementNode = (Node) l.get(0);
1154:                    //<!ELEMENT element (extension*, embedded?, column*, foreign-key?, 
1155:                    // index?, unique?, extension*)>
1156:                    Map elementChildren = groupChildrenByName(elementNode);
1157:                    if (fc.parseORM()) {
1158:                        Node n = elementNode.getAttributes().getNamedItem(
1159:                                "column");
1160:                        if (n != null) {
1161:                            fc.addColumn(new SpeedoColumn(n.getNodeValue()));
1162:                        }
1163:                        l = (List) elementChildren.get("column");
1164:                        if (l != null) {
1165:                            for (int i = 0; i < l.size(); i++) {
1166:                                fc.addColumn(getColumn((Node) l.get(i)));
1167:                            }
1168:                        }
1169:                        //<!ATTLIST element table CDATA #IMPLIED>
1170:                        n = elementNode.getAttributes().getNamedItem("table");
1171:                        if (n != null) {
1172:                            if (fc.table == null) {
1173:                                fc.table = new SpeedoTable();
1174:                            } else {
1175:                                logger.log(BasicLevel.WARN,
1176:                                        "Specify two tables for the "
1177:                                                + fc.field.getSourceDesc()
1178:                                                + ": " + fc.table.name
1179:                                                + " and " + n.getNodeValue());
1180:                            }
1181:                            fc.table.name = n.getNodeValue();
1182:                        }
1183:                    }
1184:
1185:                    unmanaged(new String[] { "serialized", "delete-action",
1186:                            "update-action", "indexed", "unique" },
1187:                            new String[] { "embedded", "foreign-key", "unique",
1188:                                    "index" }, elementNode, fc.fieldChildren);
1189:                }
1190:                if (!fc.parseORM()) {
1191:                    return;
1192:                }
1193:                if (fc.join != null && fc.field.moClass.containsJoin(fc.join)) {
1194:                    fc.field.moClass.removeJoin(fc.join);
1195:                }
1196:                if (fc.table != null || fc.join != null) {
1197:                    // The collection is stored in a join table
1198:                    if (fc.join == null) {
1199:                        // the user specified a table without join. Maybe the join to 
1200:                        // this table is already defined at class level
1201:                        SpeedoJoin[] js = fc.field.moClass.joinToExtTables;
1202:                        if (js != null) {
1203:                            for (int i = 0; i < js.length; i++) {
1204:                                if (js[i].extTable != null
1205:                                        && fc.table.name
1206:                                                .equals(js[i].extTable.name)) {
1207:                                    //The join to this table is already defined at class level
1208:                                    // use it
1209:                                    fc.field.join = js[i];
1210:                                    i = js.length;
1211:                                }
1212:                            }
1213:                            if (fc.field.join == null) {
1214:                                //no existing join found, create a new one
1215:                                fc.join = new SpeedoJoin();
1216:                            }
1217:                        }
1218:                    }
1219:                    fc.field.join = fc.join;
1220:                    fc.field.join.extTable = fc.table;
1221:                    fc.field.join.mainTable = fc.field.moClass.mainTable;
1222:                } else {
1223:                    // The collection is stored in the table of the referenced state
1224:                    fc.field.join = new SpeedoJoin();
1225:                }
1226:                fc.field.columns = fc.getColumns();
1227:            }
1228:
1229:            private void treatSimpleField(FieldContext fc) {
1230:                if (!fc.parseORM()) {
1231:                    return;
1232:                }
1233:                //The field is a primitive field OR a mono valued reference to 
1234:                // another persistent class
1235:                if (fc.join != null) { //join sub element specified
1236:                    if (fc.table == null) { //no table name specified in field
1237:                        fc.table = new SpeedoTable();
1238:                        //allocate a defaut name for the secondary table
1239:                        fc.table.name = fc.field.moClass.name.toUpperCase()
1240:                                + "_" + fc.field.name.toUpperCase();
1241:                    }
1242:                    fc.field.join = fc.join;
1243:                    fc.field.join.extTable = fc.table;
1244:                    fc.field.join.mainTable = fc.field.moClass.mainTable;
1245:                    if (!fc.field.moClass.containsJoin(fc.field.join)) {
1246:                        fc.field.moClass.addJoin(fc.field.join);
1247:                    }
1248:                } else if (fc.table != null) {
1249:                    if (fc.field.moClass.mainTable != null
1250:                            && fc.table.name
1251:                                    .equals(fc.field.moClass.mainTable.name)) {
1252:                        //the user specified the same table than the main table
1253:                        // without join.
1254:                        fc.table = null;
1255:                    }
1256:                    if (fc.table != null) {
1257:                        logger
1258:                                .log(BasicLevel.INFO,
1259:                                        "The user specified a secondary table without join columns");
1260:                        if (fc.field.moClass.getExtTable(fc.table.name, false) != fc.table) {
1261:                            logger
1262:                                    .log(BasicLevel.INFO,
1263:                                            "The user specified a secondary table without join columns");
1264:                            fc.field.join = new SpeedoJoin();
1265:                            fc.field.join.mainTable = fc.field.moClass.mainTable;
1266:                            fc.field.join.extTable = fc.table;
1267:                            fc.field.moClass.addJoin(fc.field.join);
1268:                        } else {
1269:                            logger.log(BasicLevel.DEBUG, "Field '"
1270:                                    + fc.field.name
1271:                                    + " is mapped into the table '"
1272:                                    + fc.table.name + "'.");
1273:                        }
1274:                    }
1275:                }
1276:                if (fc.table == null) {
1277:                    fc.table = fc.field.moClass.mainTable;
1278:                }
1279:                if (fc.columns != null) {
1280:                    for (int i = 0; i < fc.columns.size(); i++) {
1281:                        SpeedoColumn column = (SpeedoColumn) fc.columns.get(i);
1282:                        if (column.table == null) {
1283:                            column.table = fc.table;
1284:                        }
1285:                        fc.field.addColumn(column);
1286:                        logger.log(BasicLevel.DEBUG, "specify column "
1287:                                + column.name + " to the field "
1288:                                + fc.field.name + ": " + fc.field.columns);
1289:                    }
1290:                } else {
1291:                    //no column specified, the mapping will be defined later
1292:                    // when we will have more information about the field type. 
1293:                }
1294:
1295:            }
1296:
1297:            private void treatFetchGroupNode(Node fetchNode, SpeedoClass moClass)
1298:                    throws SpeedoException {
1299:                SpeedoFetchGroup fg = treatFetchGroupTree(fetchNode, moClass);
1300:                moClass.fetchGroups.put(fg.name, fg);
1301:            }
1302:
1303:            private SpeedoFetchGroup treatFetchGroupTree(Node fetchNode,
1304:                    SpeedoClass fieldOwner) throws SpeedoException {
1305:                //<!ELEMENT fetch-group (fetch-group|field)*>
1306:                SpeedoFetchGroup fg = new SpeedoFetchGroup();
1307:                //<!ATTLIST fetch-group name CDATA #REQUIRED>
1308:                fg.name = getStringAttributeValue(fetchNode, "name", null);
1309:                //<!ATTLIST fetch-group post-load (true|false) #IMPLIED>
1310:                fg.postLoad = getBooleanAttributeValue(fetchNode, "post-load",
1311:                        false);
1312:                Map fgChildren = groupChildrenByName(fetchNode);
1313:                List fgs = (List) fgChildren.get("fetch-group");
1314:                if (fgs != null) {
1315:                    for (Iterator fgIt = fgs.iterator(); fgIt.hasNext();) {
1316:                        Node fgNode = (Node) fgIt.next();
1317:                        fg
1318:                                .addFetchGroup(treatFetchGroupTree(fgNode,
1319:                                        fieldOwner));
1320:                    }
1321:                }
1322:
1323:                List fields = (List) fgChildren.get("field");
1324:                if (fields != null) {
1325:                    for (Iterator fieldIt = fields.iterator(); fieldIt
1326:                            .hasNext();) {
1327:                        Node fieldNode = (Node) fieldIt.next();
1328:                        SpeedoField sf = new SpeedoField();
1329:                        sf.name = getStringAttributeValue(fieldNode, "name",
1330:                                null);
1331:                        fg.addField(sf);
1332:                        //depth for a field
1333:                        String depth = getStringAttributeValue(fieldNode,
1334:                                "fetch-depth", null);
1335:                        if (depth == null) {
1336:                            depth = getStringAttributeValue(fieldNode, "depth",
1337:                                    null);
1338:                            logger
1339:                                    .log(BasicLevel.WARN,
1340:                                            "attribute 'depth' is deprecated, use 'fetch-depth'.");
1341:                        }
1342:                        if (depth != null) {
1343:                            sf.depth = new Integer(depth).intValue();
1344:                        }
1345:                    }
1346:                }
1347:                return fg;
1348:            }
1349:
1350:            private static String getStringAttributeValue(Node node,
1351:                    String attribName, String defaultValue) {
1352:                Node n = node.getAttributes().getNamedItem(attribName);
1353:                if (n != null) {
1354:                    return n.getNodeValue();
1355:                } else {
1356:                    return defaultValue;
1357:                }
1358:            }
1359:
1360:            private static boolean getBooleanAttributeValue(Node node,
1361:                    String attribName, boolean defaultValue) {
1362:                Node n = node.getAttributes().getNamedItem(attribName);
1363:                if (n != null) {
1364:                    return Boolean.valueOf(n.getNodeValue()).booleanValue();
1365:                } else {
1366:                    return defaultValue;
1367:                }
1368:            }
1369:
1370:            private void unmanaged(String[] attributeNames, String[] nodeTypes,
1371:                    Node node, Map type2nodes) {
1372:                String parent = node.getNodeName();
1373:                if (attributeNames != null) {
1374:                    for (int i = 0; i < attributeNames.length; i++) {
1375:                        Node n = node.getAttributes().getNamedItem(
1376:                                attributeNames[i]);
1377:                        if (n != null) {
1378:                            logger.log(BasicLevel.WARN,
1379:                                    "Speedo does not support yet the "
1380:                                            + attributeNames[i]
1381:                                            + " attribute in " + parent
1382:                                            + " tag.");
1383:                        }
1384:                    }
1385:                }
1386:                if (nodeTypes != null) {
1387:                    for (int i = 0; i < nodeTypes.length; i++) {
1388:                        List l = (List) type2nodes.get(nodeTypes[i]);
1389:                        if (l != null) {
1390:                            for (int j = 0; j < l.size(); j++) {
1391:                                logger.log(BasicLevel.WARN,
1392:                                        "Speedo does not support yet the "
1393:                                                + nodeTypes[i]
1394:                                                + " sub element in " + parent
1395:                                                + " tag.");
1396:                            }
1397:                        }
1398:                    }
1399:                }
1400:            }
1401:
1402:            private static class FieldContext {
1403:                /**
1404:                 * The Speedo meta object representing the field: 
1405:                 * SpeedoField or SpeedoInheritedField
1406:                 */
1407:                public SpeedoCommonField field;
1408:                /**
1409:                 * The join found associated to this field
1410:                 */
1411:                public SpeedoJoin join;
1412:                /**
1413:                 * The table instance 
1414:                 */
1415:                public SpeedoTable table;
1416:                public List columns;
1417:                public List idxColumns;
1418:                public Node fieldNode;
1419:                public Map fieldChildren;
1420:
1421:                public void addColumn(SpeedoColumn col) {
1422:                    if (columns == null) {
1423:                        columns = new ArrayList();
1424:                    }
1425:                    columns.add(col);
1426:                }
1427:
1428:                public boolean parseORM() {
1429:                    return !(field instanceof  SpeedoField)
1430:                            || !((SpeedoField) field).mappedByReversefield;
1431:                }
1432:
1433:                public void parseTableAttribute(Node node, Logger logger) {
1434:                    Node n = fieldNode.getAttributes().getNamedItem("table");
1435:                    if (n != null) {
1436:                        join = field.moClass.getJoin(n.getNodeValue(), true);
1437:                        table = join.extTable;
1438:                        if (logger.isLoggable(BasicLevel.DEBUG)) {
1439:                            if (field instanceof  SpeedoField) {
1440:                                logger.log(BasicLevel.DEBUG, "specify table "
1441:                                        + table.name + " to the field "
1442:                                        + field.name + ": " + field.columns);
1443:                            } else {
1444:                                logger.log(BasicLevel.DEBUG, "specify table "
1445:                                        + table.name
1446:                                        + " to the inherited field "
1447:                                        + field.name + ": " + field.columns);
1448:                            }
1449:                        }
1450:                    }
1451:                }
1452:
1453:                public SpeedoColumn[] getColumns() {
1454:                    if (columns == null || columns.size() == 0) {
1455:                        return null;
1456:                    } else {
1457:                        return (SpeedoColumn[]) columns
1458:                                .toArray(new SpeedoColumn[columns.size()]);
1459:                    }
1460:                }
1461:            }
1462:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.