Source Code Cross Referenced for ModelMapping.java in  » Database-ORM » XORM » org » xorm » 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 » XORM » org.xorm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:            $Header: /cvsroot/xorm/xorm/src/org/xorm/ModelMapping.java,v 1.57 2004/05/04 18:57:09 wbiggs Exp $
003:
004:            This file is part of XORM.
005:
006:            XORM is free software; you can redistribute it and/or modify
007:            it under the terms of the GNU General Public License as published by
008:            the Free Software Foundation; either version 2 of the License, or
009:            (at your option) any later version.
010:
011:            XORM is distributed in the hope that it will be useful,
012:            but WITHOUT ANY WARRANTY; without even the implied warranty of
013:            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:            GNU General Public License for more details.
015:
016:            You should have received a copy of the GNU General Public License
017:            along with XORM; if not, write to the Free Software
018:            Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         */
020:        package org.xorm;
021:
022:        import java.beans.PropertyDescriptor;
023:        import java.io.ByteArrayInputStream;
024:        import java.io.ByteArrayOutputStream;
025:        import java.io.InputStream;
026:        import java.io.IOException;
027:        import java.util.ArrayList;
028:        import java.util.Collection;
029:        import java.util.HashMap;
030:        import java.util.HashSet;
031:        import java.util.Iterator;
032:        import java.util.List;
033:        import java.util.Properties;
034:        import java.util.StringTokenizer;
035:        import java.util.logging.Logger;
036:
037:        import javax.jdo.JDOFatalException;
038:        import javax.jdo.JDOFatalUserException;
039:        import javax.jdo.JDOUserException;
040:        import javax.jdo.spi.JDOImplHelper;
041:        import javax.jdo.spi.PersistenceCapable;
042:        import javax.sql.DataSource;
043:
044:        import org.jdom.Document;
045:        import org.jdom.Element;
046:        import org.jdom.JDOMException;
047:        import org.jdom.input.SAXBuilder;
048:        import org.xml.sax.EntityResolver;
049:        import org.xml.sax.InputSource;
050:
051:        import org.xorm.datastore.Column;
052:        import org.xorm.datastore.ConnectionInfo;
053:        import org.xorm.datastore.Table;
054:        import org.xorm.datastore.sql.SQLConnectionInfo;
055:        import org.xorm.datastore.sql.SQLType;
056:        import org.xorm.util.FieldDescriptor;
057:        import org.xorm.util.jdoxml.*;
058:
059:        /**
060:         * Represents the full set of mappings for an object model.
061:         */
062:        public class ModelMapping implements  Configurable, I15d {
063:            protected static Logger logger = Logger
064:                    .getLogger("org.xorm.ModelMapping");
065:
066:            public static final String XORM_VENDOR_NAME = "XORM";
067:
068:            public static final String ATTR_SOURCE = "source";
069:            public static final String ATTR_TARGET = "target";
070:            public static final String ATTR_ORDER_BY = "order-by";
071:            public static final String ATTR_INDEX = "index";
072:            public static final String ATTR_FILTER = "filter";
073:            public static final String ATTR_PARAMETERS = "parameters";
074:            public static final String ATTR_VARIABLES = "variables";
075:            public static final String ATTR_ORDERING = "ordering";
076:            public static final String ATTR_IMPORTS = "imports";
077:
078:            public static final String DATABASE_XML = "org.xorm.datastore.database";
079:            public static final String DATABASE_DTD = "/org/xorm/datastore/database.dtd";
080:
081:            public static final String OPTION_VALIDATE_XML = "org.xorm.option.ValidateXML";
082:            public static final String OPTION_BOOTSTRAP_JDO = "org.xorm.option.BootstrapJDO";
083:            public static final String OPTION_DEFAULT_MAPPING = "org.xorm.option.DefaultMapping";
084:            public static final String OPTION_ONLY_CONFIGURED_PROPERTIES = "org.xorm.option.onlyConfiguredProperties";
085:
086:            private HashMap classToMapping = new HashMap();
087:            private HashMap nameToTable = new HashMap();
088:            private Properties properties;
089:            private InterfaceManagerFactory factory;
090:            private boolean validateXML = true;
091:            private boolean useDefaultMapping = false;
092:            private boolean registerClasses = false;
093:            private boolean usingDatabaseMetaData = false;
094:
095:            public void setFactory(InterfaceManagerFactory factory) {
096:                this .factory = factory;
097:            }
098:
099:            public void addClassMapping(ClassMapping mapping) {
100:                Class clazz = mapping.getMappedClass();
101:                // System.out.println("Registering class: " + clazz.getName());
102:                classToMapping.put(clazz, mapping);
103:
104:                if (registerClasses) {
105:                    // Register XORM-specific classes' JDO Metadata
106:
107:                    if (!PersistenceCapable.class.isAssignableFrom(clazz)) {
108:                        InterfaceInvocationHandler handler = new InterfaceInvocationHandler(
109:                                factory, mapping, null);
110:                        PersistenceCapable pc = (PersistenceCapable) handler
111:                                .newProxy();
112:
113:                        Collection managedFields = mapping.getManagedFields();
114:                        int len = managedFields.size();
115:                        String[] fieldNames = new String[len];
116:                        Class[] fieldTypes = new Class[len];
117:                        byte[] fieldFlags = new byte[len];
118:                        int i = 0;
119:                        Iterator it = managedFields.iterator();
120:                        while (it.hasNext()) {
121:                            FieldDescriptor fd = mapping
122:                                    .getFieldDescriptor((String) it.next());
123:                            fieldNames[i] = fd.name;
124:                            fieldTypes[i] = fd.type;
125:                            fieldFlags[i] = (byte) (pc.CHECK_READ | pc.CHECK_WRITE);
126:                            i++;
127:                        }
128:
129:                        // Register it with JDOImplHelper
130:                        JDOImplHelper.registerClass(clazz, fieldNames,
131:                                fieldTypes, fieldFlags, null, // PC superclasses not supported
132:                                pc);
133:                    }
134:                }
135:            }
136:
137:            /**
138:             * Retrieves a ClassMapping for the specified class.  If the class
139:             * itself is not mapped, but a superclass or superinterface is mapped,
140:             * that mapping is cloned and used for the specified class.
141:             * @exception JDOUserException if no applicable mapping is found
142:             */
143:            public ClassMapping getClassMapping(Class clazz) {
144:                ClassMapping mapping = getClassMappingImpl(clazz);
145:                if (mapping == null) {
146:                    throw new JDOUserException(I18N.msg("E_no_class_mapping",
147:                            clazz.getName()));
148:                }
149:                return mapping;
150:            }
151:
152:            private ClassMapping getClassMappingImpl(Class clazz) {
153:                // First check the cache of previously loaded mappings
154:                if (classToMapping.containsKey(clazz)) {
155:                    return (ClassMapping) classToMapping.get(clazz);
156:                }
157:                ClassMapping mapping;
158:                if ((mapping = loadClassMapping(clazz)) == null) {
159:                    boolean found = false;
160:                    Class[] interfaces = clazz.getInterfaces();
161:                    for (int i = 0; i < interfaces.length; i++) {
162:                        if ((mapping = getClassMappingImpl(interfaces[i])) != null) {
163:                            found = true;
164:                            break;
165:                        }
166:                    }
167:                    if (!found) {
168:                        /*              
169:                                        if(!clazz.isInterface()){
170:                                        //try superclass
171:                         */
172:                        Class super class = clazz.getSuperclass();
173:                        if ((super class != null)
174:                                && ((mapping = getClassMappingImpl(super class)) != null)) {
175:                            found = true;
176:                        }
177:                        /*
178:                        } else {
179:                        //try to find class implementing this iterface, first found will be used
180:                        logger.info("loking for implementation for interface "+clazz);
181:                        Iterator classesIter = classToMapping.keySet().iterator();
182:                        while (classesIter.hasNext()) {
183:                          Class nextClass = (Class) classesIter.next();
184:                          if(clazz.isAssignableFrom(nextClass)){
185:                            logger.info("found matching class "+nextClass);
186:                            mapping = (ClassMapping)classToMapping.get(nextClass);
187:                            found = true;
188:                            break;
189:                          }
190:                        }
191:                        }
192:                         */
193:                    }
194:                    if (found && !mapping.getMappedClass().equals(clazz)) {
195:                        // Simulate the mapping
196:                        //System.out.println("Cloning ClassMapping for " + mapping.getMappedClass() + " to " + clazz);
197:                        mapping = (ClassMapping) mapping.clone();
198:                        mapping.clazz = clazz;
199:                        addClassMapping(mapping);
200:                        //classToMapping.put(clazz, mapping);
201:                    }
202:                }
203:                return mapping;
204:            }
205:
206:            /**
207:             * Loads the class mapping information by reading the corresponding
208:             * JDO metadata files.
209:             * 
210:             * @param clazz the interface or abstract class class to be loaded
211:             * @return a ClassMapping object representing the mappings, or
212:             *   null if no mapping exists.
213:             */
214:            private synchronized ClassMapping loadClassMapping(Class clazz) {
215:                // First request for this class; read appropriate JDO files.
216:                String name = clazz.getName();
217:                StringTokenizer toke = new StringTokenizer(name, ".");
218:                StringBuffer path = new StringBuffer("/");
219:                while (toke.hasMoreTokens()) {
220:                    path.append(toke.nextToken());
221:                    if (toke.hasMoreTokens()) {
222:                        path.append("/");
223:                    } else {
224:                        path.append(".jdo");
225:                    }
226:                }
227:                InputStream jdo = getClass().getResourceAsStream(
228:                        path.toString());
229:                if (jdo == null) {
230:                    // Try package file
231:                    int pos = path.toString().lastIndexOf("/");
232:                    if (pos > 0) {
233:                        path.delete(pos, path.length());
234:                        path.append(".jdo");
235:                    }
236:                    jdo = getClass().getResourceAsStream(path.toString());
237:                }
238:                if (jdo == null) {
239:                    // No mapping exists
240:                    classToMapping.put(clazz, null);
241:                    return null;
242:                } else {
243:                    initJDO(jdo);
244:                    return (ClassMapping) classToMapping.get(clazz);
245:                }
246:            }
247:
248:            public Table getTable(String name) {
249:                return (Table) nameToTable.get(name);
250:            }
251:
252:            /**
253:             * Initializes an empty ModelMapping that will be populated
254:             * on demand by reading JDO files, or can be hand-populated
255:             * by the user.
256:             * @param props the Properties to use
257:             */
258:            public void setProperties(Properties props) {
259:                this .properties = props;
260:
261:                validateXML = !"false".equalsIgnoreCase(properties
262:                        .getProperty(OPTION_VALIDATE_XML));
263:                useDefaultMapping = "true".equalsIgnoreCase(properties
264:                        .getProperty(OPTION_DEFAULT_MAPPING));
265:
266:                String databaseXML = properties.getProperty(DATABASE_XML);
267:                if (databaseXML != null) {
268:                    SAXBuilder biff = new SAXBuilder(validateXML);
269:                    biff.setEntityResolver(new EntityResolver() {
270:                        public InputSource resolveEntity(String publicId,
271:                                String systemId) {
272:                            if ("database.dtd".equals(systemId)) {
273:                                return new InputSource(getClass()
274:                                        .getResourceAsStream(DATABASE_DTD));
275:                            }
276:                            return null;
277:                        }
278:                    });
279:                    InputStream testStream = getClass().getResourceAsStream(
280:                            databaseXML);
281:                    if (testStream == null) {
282:                        testStream = Thread.currentThread()
283:                                .getContextClassLoader().getResourceAsStream(
284:                                        databaseXML);
285:                    }
286:                    if (testStream == null) {
287:                        throw new JDOFatalUserException(I18N.msg(
288:                                "E_locate_db_xml", databaseXML));
289:                    }
290:                    InputSource inputSource = new InputSource(testStream);
291:
292:                    // Fake out Crimson
293:                    inputSource.setSystemId(getClass()
294:                            .getResource(DATABASE_DTD).toString());
295:
296:                    try {
297:                        Document doc = biff.build(inputSource);
298:                        Element root = doc.getRootElement();
299:                        parseTables(root);
300:                    } catch (JDOMException e) {
301:                        throw new JDOFatalException(I18N.msg("E_parse_db_xml",
302:                                databaseXML), e);
303:                    } catch (IOException e) {
304:                        throw new JDOFatalException(I18N.msg("E_parse_db_xml",
305:                                databaseXML), e);
306:                    }
307:                } else {
308:                    // DATABASE_XML was not defined.
309:                    usingDatabaseMetaData = true;
310:                    logger
311:                            .info(DATABASE_XML
312:                                    + " not defined, will dynamically use DatabaseMetaData");
313:                }
314:
315:                // Check for bootstrap loading of JDO files
316:                String bootstrap = properties.getProperty(OPTION_BOOTSTRAP_JDO);
317:                if (bootstrap != null) {
318:                    String[] parts = bootstrap.split(",");
319:                    registerClasses = true;
320:                    for (int i = 0; i < parts.length; i++) {
321:                        InputStream jdo = getClass().getResourceAsStream(
322:                                parts[i]);
323:                        initJDO(jdo);
324:                    }
325:                    registerClasses = false;
326:                }
327:            }
328:
329:            /**
330:             * Returns true if the interface type passed in has been configured
331:             * via the mapping file to be persisted.
332:             * Note that this is NOT the same thing as checking if an instance
333:             * that implements the interface is managed, and in particular, a call to 
334:             * mgr.isManagedType(persistentInstance.getClass()) 
335:             * will NOT return true.
336:             */
337:            public boolean isManagedType(Class type) {
338:                return (getClassMappingImpl(type) != null);
339:            }
340:
341:            /** Used as a utility method from init. */
342:            private String getPackagedClassName(String className,
343:                    String defaultPackage) {
344:                if (defaultPackage == null || className.indexOf('.') != -1) {
345:                    return className;
346:                }
347:                return defaultPackage + '.' + className;
348:            }
349:
350:            /**
351:             * Uses JDOM to load configuration from an XML .jdo file.
352:             */
353:            private void initJDO(InputStream mappingStream) {
354:                try {
355:                    JDOPackage jdoPackage = JDOXML.read(mappingStream,
356:                            validateXML);
357:                    String defaultPackage = jdoPackage.getName();
358:                    if ("".equals(defaultPackage)) {
359:                        defaultPackage = null;
360:                    }
361:
362:                    if (usingDatabaseMetaData) {
363:                        // The user didn't specify a DATABASE_XML file, so we need
364:                        // to load all tables referenced in the .jdo file from the
365:                        // database.
366:                        loadReferencedTablesFromMetaData(jdoPackage);
367:                    }
368:
369:                    // Look at the classes twice: first create ClassMapping
370:                    // instances with tables only, then fill in the details.
371:                    // This is done so that different ClassMappings can use
372:                    // each other's default fetch group settings, possibly
373:                    // circularly.
374:                    Iterator i = jdoPackage.getClasses().iterator();
375:                    while (i.hasNext()) {
376:                        JDOClass jdoClass = (JDOClass) i.next();
377:                        String className = getPackagedClassName(jdoClass
378:                                .getName(), defaultPackage);
379:                        Class c = Class.forName(className);
380:                        ClassMapping classMapping;
381:                        if ("true"
382:                                .equalsIgnoreCase(properties
383:                                        .getProperty(OPTION_ONLY_CONFIGURED_PROPERTIES))) {
384:                            classMapping = new ClassMapping(this , c, jdoClass);
385:                        } else {
386:                            classMapping = new ClassMapping(this , c);
387:                        }
388:
389:                        Iterator exts = jdoClass.getExtensions().iterator();
390:                        JDOExtension extension;
391:                        Class dsi = null;
392:                        Table t = null;
393:                        while (exts.hasNext()) {
394:                            extension = (JDOExtension) exts.next();
395:                            if (XORM_VENDOR_NAME.equals(extension
396:                                    .getVendorName())) {
397:                                String key = extension.getKey();
398:                                if ("datastore-identity-type".equals(key)) {
399:                                    dsi = Class.forName(extension.getValue());
400:                                } else if ("table".equals(key)) {
401:                                    String tableName = extension.getValue();
402:                                    t = getTable(tableName);
403:                                    if (t == null) {
404:                                        throw new JDOFatalUserException(I18N
405:                                                .msg("E_no_table_definition",
406:                                                        tableName));
407:                                    }
408:                                }
409:                            }
410:                        }
411:
412:                        if (t == null && !useDefaultMapping) {
413:                            throw new JDOFatalUserException(I18N.msg(
414:                                    "E_no_table", c.getName()));
415:                        }
416:
417:                        classMapping.setTable(t);
418:                        classMapping.setDatastoreIdentityType(dsi);
419:                        addClassMapping(classMapping);
420:                    }
421:                    i = jdoPackage.getClasses().iterator();
422:                    while (i.hasNext()) {
423:                        JDOClass jdoClass = (JDOClass) i.next();
424:                        parseClass(jdoClass, defaultPackage);
425:                    }
426:
427:                } catch (IOException e) {
428:                    throw new JDOFatalException(I18N.msg("E_parse_jdo_xml"), e);
429:                } catch (ClassNotFoundException e) {
430:                    throw new JDOFatalException(I18N.msg("E_jdo_xml_no_class",
431:                            e.getMessage()));
432:                }
433:            }
434:
435:            /**
436:             * Parses a <class> element passed in as the first parameter.
437:             */
438:            private void parseClass(JDOClass jdoClass, String defaultPackage)
439:                    throws ClassNotFoundException {
440:                String className = getPackagedClassName(jdoClass.getName(),
441:                        defaultPackage);
442:                Class c = Class.forName(className);
443:                ClassMapping classMapping = getClassMapping(c);
444:                Table t = classMapping.getTable();
445:
446:                Iterator exts;
447:                JDOExtension extension;
448:                // read fields
449:                Iterator j = jdoClass.getFields().iterator();
450:                while (j.hasNext()) {
451:                    JDOField field = (JDOField) j.next();
452:                    exts = field.getExtensions().iterator();
453:                    while (exts.hasNext()) {
454:                        extension = (JDOExtension) exts.next();
455:                        if (XORM_VENDOR_NAME.equals(extension.getVendorName())) {
456:                            String key = extension.getKey();
457:                            if ("column".equals(key)) {
458:                                Column c2 = t.getColumnByName(extension
459:                                        .getValue());
460:                                if (c2 == null) {
461:                                    throw new JDOFatalUserException(I18N.msg(
462:                                            "E_no_column",
463:                                            extension.getValue(), t.getName(),
464:                                            jdoClass.getName()));
465:                                }
466:                                classMapping.setColumn(field.getName(), c2,
467:                                        field.isDefaultFetchGroup());
468:                                if (field.getNullValue().equals(
469:                                        JDONullValue.EXCEPTION)) {
470:                                    // TODO: should this be done here?
471:                                    c2.setNonNull(true);
472:                                }
473:                            } else if ("inverse".equals(key)) {
474:                                classMapping.setInverse(field.getName(),
475:                                        extension.getValue());
476:                            }
477:                        } // XORM is vendor-name
478:                    } // end extension elements
479:                    // See if field is a collection
480:                    JDOCollection collection = field.getCollection();
481:                    if (collection != null) {
482:                        RelationshipMapping rm = parseRelationship(collection,
483:                                c, defaultPackage, field, jdoClass);
484:                        classMapping.setRelationship(field.getName(), rm);
485:                    }
486:                }
487:            }
488:
489:            private RelationshipMapping parseRelationship(JDOCollection root,
490:                    Class ownerClass, String defaultPackage, JDOField field,
491:                    JDOClass jdoClass) throws ClassNotFoundException {
492:                RelationshipMapping relationship = new RelationshipMapping();
493:                String elementType = root.getElementType();
494:                elementType = getPackagedClassName(elementType, defaultPackage);
495:
496:                Class elementClass = Class.forName(elementType);
497:
498:                RelationshipMapping.Endpoint source = new RelationshipMapping.Endpoint();
499:                source.setCollectionType(source.SET);
500:                source.setElementClass(elementClass);
501:                relationship.setSource(source);
502:
503:                RelationshipMapping.Endpoint target = new RelationshipMapping.Endpoint();
504:                target.setCollectionType(target.SET);
505:                relationship.setTarget(target);
506:
507:                Table table = null;
508:                Iterator i = root.getExtensions().iterator();
509:                String sourceStr = null;
510:                String targetStr = null;
511:                String indexStr = null;
512:                // Added support for filtered collections (Dan Checkoway, 6/26/03)
513:                String filterStr = null;
514:                String parametersStr = null;
515:                String variablesStr = null;
516:                String importsStr = null;
517:                while (i.hasNext()) {
518:                    JDOExtension element = (JDOExtension) i.next();
519:                    if (XORM_VENDOR_NAME.equals(element.getVendorName())) {
520:                        String key = element.getKey();
521:                        String value = element.getValue();
522:                        boolean redefined = false;
523:                        if ("table".equals(key)) {
524:                            redefined = table != null;
525:                            table = getTable(value);
526:                            if (table == null) {
527:                                throw new JDOFatalUserException(I18N.msg(
528:                                        "E_unknown_table", value));
529:                            }
530:                        } else if (ATTR_SOURCE.equals(key)) {
531:                            redefined = sourceStr != null;
532:                            sourceStr = value;
533:                        } else if (ATTR_TARGET.equals(key)) {
534:                            redefined = targetStr != null;
535:                            targetStr = value;
536:                        } else if (ATTR_ORDER_BY.equals(key)) {
537:                            redefined = relationship.getOrderBy() != null;
538:                            relationship.setOrderBy(value);
539:                        } else if (ATTR_INDEX.equals(key)) {
540:                            redefined = indexStr != null;
541:                            indexStr = value;
542:                        } else if (ATTR_FILTER.equals(key)) {
543:                            // Filtered collection query
544:                            redefined = filterStr != null;
545:                            filterStr = value;
546:                        } else if (ATTR_PARAMETERS.equals(key)) {
547:                            // Filtered collection query parameters
548:                            redefined = parametersStr != null;
549:                            parametersStr = value;
550:                        } else if (ATTR_VARIABLES.equals(key)) {
551:                            // Filtered collection query variables
552:                            redefined = variablesStr != null;
553:                            variablesStr = value;
554:                        } else if (ATTR_ORDERING.equals(key)) {
555:                            // JDO-style ordering
556:                            redefined = relationship.getOrdering() != null;
557:                            relationship.setOrdering(value);
558:                        } else if (ATTR_IMPORTS.equals(key)) {
559:                            redefined = importsStr != null;
560:                            importsStr = value;
561:                        }
562:                        if (redefined) {
563:                            throw new JDOFatalUserException(I18N.msg(
564:                                    "E_collection_redefinition", key, field
565:                                            .getName(), jdoClass.getName()));
566:                        }
567:                    }
568:                } // for each "extension" element
569:
570:                if (sourceStr == null && filterStr == null) {
571:                    if (useDefaultMapping) {
572:                        sourceStr = "source_" + ownerClass.getName();
573:                    } else {
574:                        // You have to specify either a source or a filter or both.
575:                        throw new JDOFatalUserException(I18N.msg(
576:                                "E_collection_no_source", field.getName(),
577:                                jdoClass.getName()));
578:                    }
579:                }
580:
581:                if (table == null) {
582:                    // The table wasn't explicitly specified.  We can safely
583:                    // assume that if a collection is specified without an explicit
584:                    // table, then the table is the collection element type's table.
585:                    ClassMapping mapping = getClassMapping(elementClass);
586:                    if ((table = mapping.getTable()) == null) {
587:                        // Not much we can do about this.  I don't think it will ever
588:                        // happen, but just in case...
589:                        throw new JDOFatalUserException(I18N.msg(
590:                                "E_collection_no_table", field.getName(),
591:                                jdoClass.getName()));
592:                    }
593:                    logger.fine("No table specified for collection field \""
594:                            + field.getName()
595:                            + "\"...assuming element type table: "
596:                            + table.getName());
597:                }
598:
599:                if (relationship.getOrderBy() != null
600:                        && relationship.getOrdering() != null) {
601:                    // Don't even bother trying to interpret precedence
602:                    throw new JDOFatalUserException(I18N
603:                            .msg("E_collection_order_by_and_ordering"));
604:                }
605:
606:                if (relationship.getOrdering() != null && filterStr == null) {
607:                    throw new JDOFatalUserException(I18N.msg(
608:                            "E_collection_ordering_without_filter", field
609:                                    .getName(), jdoClass.getName()));
610:                }
611:
612:                if (sourceStr != null) {
613:                    source.setColumn(table.getColumnByName(sourceStr));
614:                }
615:
616:                if (targetStr == null) {
617:                    target.setColumn(table.getPrimaryKey());
618:                } else {
619:                    // It's many-to-many.  We used to set the target's elementClass
620:                    // to signify this, but that seemed like a hack to me.  And since
621:                    // the target's elementClass was set to the owner class, which
622:                    // didn't seem to apply (if anything the target element class
623:                    // would be the collection's element class, not the owner's class),
624:                    // I added this boolean setter/getter instead.
625:                    relationship.setMToN(true);
626:                    target.setColumn(table.getColumnByName(targetStr));
627:                }
628:
629:                if (indexStr != null) {
630:                    Column c = table.getColumnByName(indexStr);
631:                    // Set the column to managed mode; we don't want
632:                    // indices to be included in Row.equals() operations
633:                    c.setManaged(true);
634:                    relationship.setIndexColumn(c);
635:                }
636:
637:                if (filterStr != null && !filterStr.equals("")) {
638:                    relationship.setFilter(filterStr);
639:                    // Only set parameters & variables if the filter is specified.
640:                    // Otherwise it would make no sense.
641:                    if (parametersStr != null && !parametersStr.equals("")) {
642:                        relationship.setParameters(parametersStr);
643:                    }
644:                    if (variablesStr != null && !variablesStr.equals("")) {
645:                        relationship.setVariables(variablesStr);
646:                    }
647:                    if (importsStr != null && !importsStr.equals("")) {
648:                        relationship.setImports(importsStr);
649:                    }
650:                }
651:
652:                return relationship;
653:            }
654:
655:            private void parseTables(Element root) {
656:                List tables = root.getChildren("table");
657:                Iterator i = tables.iterator();
658:                while (i.hasNext()) {
659:                    Element element = (Element) i.next();
660:                    String tableName = element.getAttributeValue("name");
661:                    Table table = new Table(tableName);
662:                    nameToTable.put(tableName, table);
663:                    List columns = element.getChildren("column");
664:                    Iterator j = columns.iterator();
665:                    while (j.hasNext()) {
666:                        Element colElement = (Element) j.next();
667:                        Column column = new Column(table, colElement
668:                                .getAttributeValue("name"));
669:                        if ("true".equalsIgnoreCase(colElement
670:                                .getAttributeValue("primary-key"))) {
671:                            table.setPrimaryKey(column);
672:                        }
673:                        if ("true".equalsIgnoreCase(colElement
674:                                .getAttributeValue("read-only"))) {
675:                            column.setReadOnly(true);
676:                        }
677:                        if ("true".equalsIgnoreCase(colElement
678:                                .getAttributeValue("non-null"))) {
679:                            column.setNonNull(true);
680:                        }
681:                        // Is it a sequenced column?
682:                        if (colElement.getAttributeValue("sequence") != null) {
683:                            column.setSequence(colElement
684:                                    .getAttributeValue("sequence"));
685:                        }
686:                        // Is it an autoincremented column?
687:                        if ("true".equalsIgnoreCase(colElement
688:                                .getAttributeValue("auto"))) {
689:                            column.setAutoIncremented(true);
690:                        }
691:                        // Is it manually typed?
692:                        column.setType(colElement.getAttributeValue("type"));
693:                        column
694:                                .setFormat(colElement
695:                                        .getAttributeValue("format"));
696:                    } // columns iterator
697:                    // map the table for later reference
698:                } // tables iterator
699:            }
700:
701:            /**
702:             * Generates a list of table names extracted from the JDO file
703:             * and passes each one to ConnectionInfo.describeTable(String name).
704:             */
705:            private void loadReferencedTablesFromMetaData(JDOPackage jdoPackage) {
706:                HashSet tableNames = new HashSet();
707:                for (Iterator classIter = jdoPackage.getClasses().iterator(); classIter
708:                        .hasNext();) {
709:                    JDOClass jdoClass = (JDOClass) classIter.next();
710:                    // Look at the class extensions for the "table"
711:                    for (Iterator extIter = jdoClass.getExtensions().iterator(); extIter
712:                            .hasNext();) {
713:                        JDOExtension extension = (JDOExtension) extIter.next();
714:                        if ("table".equals(extension.getKey())) {
715:                            String tableName = extension.getValue();
716:                            if (tableNames.add(tableName)) {
717:                                logger.fine("Discovered table name: "
718:                                        + tableName);
719:                            }
720:                        }
721:                    }
722:                    // Look at the class fields and everything under there
723:                    for (Iterator fieldIter = jdoClass.getFields().iterator(); fieldIter
724:                            .hasNext();) {
725:                        JDOField field = (JDOField) fieldIter.next();
726:                        // Look at the field's extensions
727:                        for (Iterator extIter = field.getExtensions()
728:                                .iterator(); extIter.hasNext();) {
729:                            JDOExtension extension = (JDOExtension) extIter
730:                                    .next();
731:                            if ("table".equals(extension.getKey())) {
732:                                String tableName = extension.getValue();
733:                                if (tableNames.add(tableName)) {
734:                                    logger.fine("Discovered table name: "
735:                                            + tableName);
736:                                }
737:                            }
738:                        }
739:
740:                        // Look at the field's collection, if there is one
741:                        JDOCollection collection = field.getCollection();
742:                        if (collection != null) {
743:                            for (Iterator extIter = collection.getExtensions()
744:                                    .iterator(); extIter.hasNext();) {
745:                                JDOExtension extension = (JDOExtension) extIter
746:                                        .next();
747:                                if ("table".equals(extension.getKey())) {
748:                                    String tableName = extension.getValue();
749:                                    if (tableNames.add(tableName)) {
750:                                        logger.fine("Discovered table name: "
751:                                                + tableName);
752:                                    }
753:                                }
754:                            }
755:                        }
756:                    }
757:                }
758:
759:                logger.fine("Discovered " + tableNames.size()
760:                        + " table names...loading them now");
761:
762:                ConnectionInfo ci = factory.getConnectionInfo();
763:                for (Iterator iter = tableNames.iterator(); iter.hasNext();) {
764:                    String tableName = (String) iter.next();
765:                    // Load it from db metadata
766:                    nameToTable.put(tableName, ci.describeTable(tableName));
767:                }
768:            }
769:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.