Source Code Cross Referenced for FetchGroupBuilder.java in  » Testing » PolePosition-0.20 » com » versant » core » metadata » 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 » Testing » PolePosition 0.20 » com.versant.core.metadata 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 1998 - 2005 Versant Corporation
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         * Versant Corporation - initial API and implementation
010:         */
011:        package com.versant.core.metadata;
012:
013:        import com.versant.core.common.Debug;
014:        import com.versant.core.metadata.parser.JdoElement;
015:        import com.versant.core.metadata.parser.JdoExtension;
016:        import com.versant.core.metadata.parser.JdoExtensionKeys;
017:
018:        import java.util.*;
019:
020:        import com.versant.core.common.BindingSupportImpl;
021:
022:        /**
023:         * This is used by MetaDataBuilder to construct fetch groups. Putting all
024:         * the fetch group stuff in one file should add some much needed sanity.
025:         */
026:        public class FetchGroupBuilder {
027:
028:            private final ModelMetaData jmd;
029:            private final boolean sendCurrentForFGWithSecFields;
030:            private final boolean readObjectBeforeWrite;
031:
032:            public FetchGroupBuilder(ModelMetaData jmd,
033:                    boolean sendCurrentForFGWithSecFields,
034:                    boolean readObjectBeforeWrite) {
035:                this .jmd = jmd;
036:                this .sendCurrentForFGWithSecFields = sendCurrentForFGWithSecFields;
037:                this .readObjectBeforeWrite = readObjectBeforeWrite;
038:            }
039:
040:            protected StoreFetchGroup createStoreFetchGroup() {
041:                return null;
042:            }
043:
044:            /**
045:             * Return the first fetch-group extension in a or null if none.
046:             */
047:            public JdoExtension findFetchGroupExt(JdoExtension[] a) {
048:                if (a == null)
049:                    return null;
050:                int n = a.length;
051:                for (int i = 0; i < n; i++) {
052:                    if (a[i].key == JdoExtensionKeys.FETCH_GROUP)
053:                        return a[i];
054:                }
055:                return null;
056:            }
057:
058:            /**
059:             * Build all the fetch groups. This must be called once all the fields for
060:             * each class have been created (including fake fields etc.).
061:             */
062:            public void buildFetchGroups(boolean quiet) {
063:                ClassMetaData[] classes = jmd.classes;
064:                int clen = classes.length;
065:
066:                // create all the groups with their field arrays
067:                if (Debug.DEBUG)
068:                    System.out.println("MDB-FGB: Creating fetch groups");
069:                for (int i = 0; i < clen; i++) {
070:                    ClassMetaData cmd = classes[i];
071:                    try {
072:                        if (cmd.pcSuperMetaData == null)
073:                            createFetchGroups(cmd, quiet);
074:                    } catch (RuntimeException e) {
075:                        cmd.addError(e, quiet);
076:                    }
077:                }
078:
079:                // resolve next-fetch-group references etc
080:                if (Debug.DEBUG) {
081:                    System.out
082:                            .println("MDB-FGB: Resolving next-fetch-group references");
083:                }
084:                for (int i = 0; i < clen; i++) {
085:                    ClassMetaData cmd = classes[i];
086:                    try {
087:                        processFetchGroups(cmd);
088:                    } catch (RuntimeException e) {
089:                        cmd.addError(e, quiet);
090:                    }
091:                }
092:
093:                // Set the sendFieldsOnFetch on FetchGroup's with secondaryField's
094:                // if required by the DataStore for the class. Also sets the
095:                // hasPrimaryFields flag on all FetchGroups.
096:                for (int i = 0; i < clen; i++) {
097:                    ClassMetaData cmd = classes[i];
098:                    // todo Commenting out these lines appeared to make no difference
099:                    //           	if (cmd.pcSuperMetaData != null && cmd.vdsClass == null) {
100:                    //           		continue;
101:                    //            }
102:                    FetchGroup[] fetchGroups = cmd.fetchGroups;
103:                    if (fetchGroups == null) {
104:                        continue;
105:                    }
106:                    for (int j = fetchGroups.length - 1; j >= 0; j--) {
107:                        FetchGroup fg = fetchGroups[j];
108:                        if (sendCurrentForFGWithSecFields
109:                                && !fg.hasPrimaryFields(true)
110:                                && fg.hasSecondaryFields()) {
111:                            fg.setSendFieldsOnFetch(true);
112:                        }
113:                        if (fg.hasPrimaryFields(false)) {
114:                            fg.setHasPrimaryFields(true);
115:                        }
116:                    }
117:                }
118:            }
119:
120:            /**
121:             * Create all groups for cmd with their field arrays and then recursively
122:             * create groups for its subclasses.
123:             */
124:            private void createFetchGroups(ClassMetaData cmd, boolean quiet) {
125:                if (cmd.fields == null) {
126:                    return; // no fields due to some previous error
127:                }
128:
129:                ArrayList groups = cmd.fgTmp = new ArrayList();
130:                HashMap nameGroupMap = cmd.nameGroupMap = new HashMap();
131:
132:                FetchGroup dfg = createDefaultFetchGroup(cmd);
133:                groups.add(dfg);
134:                nameGroupMap.put(dfg.name, dfg);
135:
136:                FetchGroup retrieveFG = createRetrieveFetchGroup(cmd);
137:                groups.add(retrieveFG);
138:                nameGroupMap.put(retrieveFG.name, retrieveFG);
139:
140:                FetchGroup allColsFG = createAllColumnsFetchGroup(cmd);
141:                groups.add(allColsFG);
142:                nameGroupMap.put(allColsFG.name, allColsFG);
143:
144:                FetchGroup dfgNoFakes = createFetchGroupDefaultNoFakes(cmd);
145:                groups.add(dfgNoFakes);
146:                nameGroupMap.put(dfgNoFakes.name, dfgNoFakes);
147:
148:                // if you add new groups here add a corresponding line to the block
149:                // towards the end of this method that caches special groups in
150:                // ClassMetaData
151:                addNotNull(createRefFetchGroup(cmd), groups, nameGroupMap);
152:                addNotNull(createDepFetchGroup(cmd), groups, nameGroupMap);
153:                addNotNull(createReqFetchGroup(cmd), groups, nameGroupMap);
154:                addNotNull(createManagedManyToManyFetchGroup(cmd), groups,
155:                        nameGroupMap);
156:
157:                // find all the user defined groups
158:                JdoElement[] elements = cmd.jdoClass.elements;
159:                int elementsLen = elements.length;
160:                for (int j = 0; j < elementsLen; j++) {
161:                    JdoElement element = elements[j];
162:                    if (!(element instanceof  JdoExtension))
163:                        continue;
164:                    JdoExtension e = (JdoExtension) element;
165:                    if (e.key != JdoExtensionKeys.FETCH_GROUP)
166:                        continue;
167:                    FetchGroup g = new FetchGroup(cmd, e.getString(),
168:                            createStoreFetchGroup());
169:                    try {
170:                        if (g.name.equals(FetchGroup.DFG_NAME)) {
171:                            throw BindingSupportImpl.getInstance().runtime(
172:                                    "The group name '" + FetchGroup.DFG_NAME
173:                                            + "' is reserved for the "
174:                                            + "default fetch group\n"
175:                                            + e.getContext());
176:                        }
177:                        if (g.name.equals(FetchGroup.REF_NAME)) {
178:                            throw BindingSupportImpl.getInstance().runtime(
179:                                    "The group name '" + FetchGroup.REF_NAME
180:                                            + "' is reserved internal use\n"
181:                                            + e.getContext());
182:                        }
183:                        if (nameGroupMap.containsKey(g.name)) {
184:                            throw BindingSupportImpl.getInstance().runtime(
185:                                    "There is already a group called: '"
186:                                            + g.name + "'\n" + e.getContext());
187:                        }
188:                        nameGroupMap.put(g.name, g);
189:                        g.extension = e;
190:                        processFetchGroupFields(cmd, g, quiet);
191:                        groups.add(g);
192:                    } catch (RuntimeException e1) {
193:                        cmd.addError(e1, quiet);
194:                    }
195:                }
196:
197:                // create an empty group for each group from our parent class that
198:                // has not been extended i.e. group defined here with same name
199:                if (cmd.pcSuperMetaData != null) {
200:                    List list = cmd.pcSuperMetaData.fgTmp;
201:                    for (int i = 0; i < list.size(); i++) {
202:                        FetchGroup sg = (FetchGroup) list.get(i);
203:                        if (nameGroupMap.containsKey(sg.name))
204:                            continue;
205:                        FetchGroup g = new FetchGroup(cmd, sg.name,
206:                                createStoreFetchGroup());
207:                        g.fields = new FetchGroupField[0];
208:                        groups.add(g);
209:                        nameGroupMap.put(g.name, g);
210:                    }
211:                }
212:
213:                // Fill in the fetchGroup for all fields creating new groups for fields
214:                // without a group that are not in the default fetch group. If the
215:                // field is a pass1 field then the optimistic locking field (if any)
216:                // is included in the group.
217:                FieldMetaData[] fields = cmd.fields;
218:                int fieldsLen = fields.length;
219:                for (int i = 0; i < fieldsLen; i++) {
220:                    FieldMetaData fmd = fields[i];
221:                    if (fmd.jdoField != null && fmd.jdoField.extensions != null) {
222:                        try {
223:                            JdoExtension e = findFetchGroupExt(fmd.jdoField.extensions);
224:                            if (e != null) {
225:                                String gname = e.getString();
226:                                fmd.fetchGroup = (FetchGroup) nameGroupMap
227:                                        .get(gname);
228:                                if (fmd.fetchGroup == null) {
229:                                    throw BindingSupportImpl.getInstance()
230:                                            .runtime(
231:                                                    "No such fetch-group: '"
232:                                                            + gname + "'\n"
233:                                                            + e.getContext());
234:                                }
235:                            }
236:                        } catch (RuntimeException e1) {
237:                            fmd.addError(e1, quiet);
238:                        }
239:                    }
240:                    if (fmd.fetchGroup == null) {
241:                        if (fmd.defaultFetchGroup) {
242:                            fmd.fetchGroup = dfg;
243:                        } else {
244:                            String name = "_" + fmd.name + cmd.qname;
245:                            for (int j = 2; nameGroupMap.containsKey(name); j++) {
246:                                name = "_" + fmd.name + j;
247:                            }
248:                            FetchGroup g = new FetchGroup(cmd, name,
249:                                    createStoreFetchGroup());
250:
251:                            ArrayList a = new ArrayList();
252:                            if (fmd.isEmbeddedRef()) {
253:                                //must add the fake fields  to the fg
254:                                if (fmd.embeddedFmds != null) {
255:                                    for (int j = 0; j < fmd.embeddedFmds.length; j++) {
256:                                        FieldMetaData embeddedFmd = fmd.embeddedFmds[j];
257:                                        a.add(new FetchGroupField(embeddedFmd));
258:                                    }
259:                                }
260:                            } else {
261:                                FetchGroupField fgf = createFetchGroupFieldWithPrefetch(fmd);
262:                                a.add(fgf);
263:                            }
264:
265:                            // classes with storeAllFields set also read all fields
266:                            // so there is no need to add the optimistic locking field
267:                            // to fetch groups
268:                            if (fmd.primaryField && !cmd.storeAllFields
269:                                    && cmd.optimisticLockingField != null) {
270:                                a.add(new FetchGroupField(
271:                                        cmd.optimisticLockingField));
272:                            }
273:
274:                            g.fields = new FetchGroupField[a.size()];
275:                            a.toArray(g.fields);
276:
277:                            groups.add(g);
278:                            nameGroupMap.put(g.name, g);
279:                            fmd.fetchGroup = g;
280:                        }
281:                    }
282:                }
283:
284:                // dig out some popular fetchgroups for quick access
285:                cmd.refFetchGroup = (FetchGroup) nameGroupMap
286:                        .get(FetchGroup.REF_NAME);
287:                cmd.depFetchGroup = (FetchGroup) nameGroupMap
288:                        .get(FetchGroup.DEP_NAME);
289:                cmd.reqFetchGroup = (FetchGroup) nameGroupMap
290:                        .get(FetchGroup.REQ_NAME);
291:                cmd.managedManyToManyFetchGroup = (FetchGroup) nameGroupMap
292:                        .get(FetchGroup.MANY_TO_MANY_NAME);
293:
294:                // process all of our subclasses
295:                ClassMetaData[] pcSubclasses = cmd.pcSubclasses;
296:                if (pcSubclasses != null) {
297:                    for (int i = pcSubclasses.length - 1; i >= 0; i--) {
298:                        createFetchGroups(cmd.pcSubclasses[i], quiet);
299:                    }
300:                }
301:
302:                if (cmd.pcSuperMetaData == null) {
303:                    Collections.sort(cmd.fgTmp);
304:                    if (cmd.pcSubclasses != null) {
305:                        doSubFGs(cmd);
306:                    }
307:
308:                }
309:
310:                if (cmd.pcSuperMetaData == null) {
311:                    createFGArrays(cmd);
312:                }
313:            }
314:
315:            /**
316:             * Create a FGF for a field with prefetching enabled if that makes sense
317:             * for the store.
318:             */
319:            protected FetchGroupField createFetchGroupFieldWithPrefetch(
320:                    FieldMetaData fmd) {
321:                return new FetchGroupField(fmd);
322:            }
323:
324:            private void addNotNull(FetchGroup g, ArrayList groups,
325:                    HashMap nameGroupMap) {
326:                if (g != null) {
327:                    groups.add(g);
328:                    nameGroupMap.put(g.name, g);
329:                }
330:            }
331:
332:            private void doSubFGs(ClassMetaData cmd) {
333:                ClassMetaData[] subCmds = cmd.pcSubclasses;
334:                if (subCmds == null)
335:                    return;
336:                ArrayList list = new ArrayList();
337:                for (int i = 0; i < subCmds.length; i++) {
338:                    ClassMetaData subCmd = subCmds[i];
339:                    Collections.sort(subCmd.fgTmp);
340:                    list.clear();
341:                    for (int j = 0; j < cmd.fgTmp.size(); j++) {
342:                        FetchGroup fetchGroup = (FetchGroup) cmd.fgTmp.get(j);
343:                        FetchGroup subFG = (FetchGroup) subCmd.nameGroupMap
344:                                .get(fetchGroup.name);
345:                        if (j == 0) {
346:                            if (!fetchGroup.name.equals(FetchGroup.DFG_NAME)
347:                                    || !subFG.name.equals(FetchGroup.DFG_NAME)) {
348:                                throw BindingSupportImpl.getInstance()
349:                                        .internal("DFG broken");
350:                            }
351:                        }
352:                        list.add(subFG);
353:                    }
354:                    subCmd.fgTmp.removeAll(list);
355:                    list.addAll(subCmd.fgTmp);
356:                    subCmd.fgTmp.clear();
357:                    subCmd.fgTmp.addAll(list);
358:                    doSubFGs(subCmd);
359:                }
360:            }
361:
362:            private void createFGArrays(ClassMetaData cmd) {
363:                indexFGs(cmd);
364:                ClassMetaData[] cmds = cmd.pcSubclasses;
365:                if (cmds == null)
366:                    return;
367:                for (int i = 0; i < cmds.length; i++) {
368:                    ClassMetaData aCmd = cmds[i];
369:                    createFGArrays(aCmd);
370:                }
371:            }
372:
373:            private void indexFGs(ClassMetaData cmd) {
374:                int ng = cmd.fgTmp.size();
375:                FetchGroup[] fga = cmd.fetchGroups = new FetchGroup[ng];
376:                FetchGroup[] sfga = cmd.sortedFetchGroups = new FetchGroup[ng];
377:                cmd.fgTmp.toArray(fga);
378:                cmd.fgTmp.toArray(sfga);
379:                Arrays.sort(sfga);
380:                for (int i = fga.length - 1; i >= 0; i--) {
381:                    if (fga[i].index == -1) {
382:                        fga[i].index = i;
383:                    }
384:                }
385:            }
386:
387:            /**
388:             * Create the default fetch group for cmd.
389:             */
390:            private FetchGroup createDefaultFetchGroup(ClassMetaData cmd) {
391:                FieldMetaData[] fields = cmd.fields;
392:                FetchGroup g = new FetchGroup(cmd, FetchGroup.DFG_NAME,
393:                        createStoreFetchGroup());
394:                int n = fields.length;
395:                ArrayList a = new ArrayList(n);
396:                for (int i = 0; i < n; i++) {
397:                    FieldMetaData fmd = fields[i];
398:                    if (!fmd.defaultFetchGroup || fmd.primaryKey)
399:                        continue;
400:                    FetchGroupField fgf = new FetchGroupField(fmd);
401:                    a.add(fgf);
402:                }
403:                n = a.size();
404:                g.fields = new FetchGroupField[n];
405:                a.toArray(g.fields);
406:                return g;
407:            }
408:
409:            /**
410:             * This creates a fetch group that contains only default fetch group fields
411:             * but no fake fields must be added here.
412:             */
413:            private FetchGroup createFetchGroupDefaultNoFakes(ClassMetaData cmd) {
414:                FetchGroup g = new FetchGroup(cmd,
415:                        FetchGroup.DFG_NAME_NO_FAKES, createStoreFetchGroup());
416:                FieldMetaData[] fields = cmd.fields;
417:                int n = fields.length;
418:                ArrayList a = new ArrayList(n);
419:                for (int i = 0; i < n; i++) {
420:                    FieldMetaData fmd = fields[i];
421:                    if (fmd.defaultFetchGroup && !fmd.fake) {
422:                        FetchGroupField fgf = new FetchGroupField(fmd);
423:                        a.add(fgf);
424:                    }
425:                }
426:                n = a.size();
427:                g.fields = new FetchGroupField[n];
428:                a.toArray(g.fields);
429:                return g;
430:            }
431:
432:            /**
433:             * Create the retrieve fetch group for cmd.
434:             */
435:            private FetchGroup createRetrieveFetchGroup(ClassMetaData cmd) {
436:                FetchGroup g = new FetchGroup(cmd, FetchGroup.RETRIEVE_NAME,
437:                        createStoreFetchGroup());
438:                FieldMetaData[] fields = cmd.fields;
439:                int n = fields.length;
440:                ArrayList a = new ArrayList(n);
441:                for (int i = 0; i < n; i++) {
442:                    FieldMetaData fmd = fields[i];
443:                    if (fmd.persistenceModifier != MDStatics.PERSISTENCE_MODIFIER_PERSISTENT)
444:                        continue;
445:                    FetchGroupField fgf = createFetchGroupFieldWithPrefetch(fmd);
446:                    a.add(fgf);
447:                }
448:                n = a.size();
449:                g.fields = new FetchGroupField[n];
450:                a.toArray(g.fields);
451:                return g;
452:            }
453:
454:            /**
455:             * Create the all columns fetch group for cmd. This implementation just
456:             * creates a dummy empty fetch group.
457:             */
458:            protected FetchGroup createAllColumnsFetchGroup(ClassMetaData cmd) {
459:                FetchGroup g = new FetchGroup(cmd, FetchGroup.ALL_COLS_NAME,
460:                        createStoreFetchGroup());
461:                g.fields = new FetchGroupField[0];
462:                return g;
463:            }
464:
465:            /**
466:             * Create the ref fetch group for cmd or return null if cmd does not
467:             * have any fields that reference other objects. Polyref and collection
468:             * fields are included. This does not fill in the nextFetchGroup and
469:             * nextKeyFetchGroup for the fields as this can only be done once all
470:             * the groups have been created.
471:             */
472:            private FetchGroup createRefFetchGroup(ClassMetaData cmd) {
473:                FieldMetaData[] fields = cmd.fields;
474:                int n = fields.length;
475:                ArrayList a = new ArrayList(n);
476:                for (int i = 0; i < n; i++) {
477:                    FieldMetaData fmd = fields[i];
478:                    if (fmd.isDirectRef() && fmd.isFake()
479:                            && fmd.inverseFieldMetaData != null) {
480:                        continue;
481:                    }
482:                    switch (fmd.category) {
483:                    case MDStatics.CATEGORY_POLYREF:
484:                        a.add(new FetchGroupField(fmd));
485:                        break;
486:                    case MDStatics.CATEGORY_COLLECTION:
487:                    case MDStatics.CATEGORY_MAP:
488:                        if (fmd.elementType == Object.class
489:                                || fmd.keyType == Object.class
490:                                || (fmd.elementType != null && fmd.elementType
491:                                        .isInterface())
492:                                || (fmd.keyType != null && fmd.keyType
493:                                        .isInterface())) {
494:                            a.add(new FetchGroupField(fmd));
495:                            break;
496:                        }
497:                    default:
498:                        ClassMetaData refmd = fmd.getRefOrValueClassMetaData();
499:                        if (refmd != null || fmd.keyTypeMetaData != null) {
500:                            a.add(new FetchGroupField(fmd));
501:                        }
502:                    }
503:                }
504:                n = a.size();
505:                if (n == 0) {
506:                    return null;
507:                }
508:                FetchGroup g = new FetchGroup(cmd, FetchGroup.REF_NAME,
509:                        createStoreFetchGroup());
510:                g.fields = new FetchGroupField[n];
511:                a.toArray(g.fields);
512:                return g;
513:            }
514:
515:            /**
516:             * Create the dependent fetch group for cmd or return null if cmd does not
517:             * have any fields that reference dependent objects. This does not fill
518:             * in the nextFetchGroup and nextKeyFetchGroup for the fields as this can
519:             * only be done once all the groups have been created.
520:             */
521:            private FetchGroup createDepFetchGroup(ClassMetaData cmd) {
522:                FieldMetaData[] fields = cmd.fields;
523:                int n = fields.length;
524:                ArrayList a = new ArrayList(n);
525:                for (int i = 0; i < n; i++) {
526:                    FieldMetaData fmd = fields[i];
527:                    if (!fmd.dependentValues && !fmd.dependentKeys)
528:                        continue;
529:                    if (fmd.category != MDStatics.CATEGORY_POLYREF) {
530:                        ClassMetaData refmd = fmd.getRefOrValueClassMetaData();
531:                        if (refmd == null && fmd.keyTypeMetaData == null)
532:                            continue;
533:                    }
534:                    a.add(new FetchGroupField(fmd));
535:                }
536:                n = a.size();
537:                if (n == 0)
538:                    return null;
539:                FetchGroup g = new FetchGroup(cmd, FetchGroup.DEP_NAME,
540:                        createStoreFetchGroup());
541:                g.fields = new FetchGroupField[n];
542:                a.toArray(g.fields);
543:                return g;
544:            }
545:
546:            /**
547:             * Create the fetch group containing required all the fields that must
548:             * be filled in the original state when persisting changes to instances.
549:             * This includes all autoset version fields ans well as autoset timestamp
550:             * fields used to implement optimistic locking.
551:             */
552:            private FetchGroup createReqFetchGroup(ClassMetaData cmd) {
553:                FieldMetaData[] fields = cmd.fields;
554:                int n = fields.length;
555:                ArrayList a = new ArrayList(n);
556:                if (readObjectBeforeWrite) {
557:                    for (int i = 0; i < n; i++) {
558:                        FieldMetaData fmd = fields[i];
559:                        if (fmd.primaryField) {
560:                            FetchGroupField fgf = new FetchGroupField(fmd);
561:                            fgf.doNotFetchObject = true;
562:                            a.add(fgf);
563:                        }
564:                    }
565:                } else {
566:                    for (int i = 0; i < n; i++) {
567:                        FieldMetaData fmd = fields[i];
568:                        if (isReqField(cmd, fmd)) {
569:                            a.add(new FetchGroupField(fmd));
570:                        }
571:                    }
572:                }
573:                n = a.size();
574:                if (n == 0)
575:                    return null;
576:                FetchGroup g = new FetchGroup(cmd, FetchGroup.REQ_NAME,
577:                        createStoreFetchGroup());
578:                g.fields = new FetchGroupField[n];
579:                a.toArray(g.fields);
580:                return g;
581:            }
582:
583:            /**
584:             * Is fmd required before changes to an instance can be persisted?
585:             */
586:            private boolean isReqField(ClassMetaData cmd, FieldMetaData fmd) {
587:                if (fmd.autoSet == MDStatics.AUTOSET_NO) {
588:                    return false;
589:                }
590:                if (fmd.typeCode == MDStatics.DATE) {
591:                    return fmd == cmd.optimisticLockingField;
592:                }
593:                return true;
594:            }
595:
596:            /**
597:             * Create the fetch group containing all the managed many-to-many fields
598:             * and all the required fields. No group is created if there are no
599:             * managed many-to-many fields.
600:             */
601:            private FetchGroup createManagedManyToManyFetchGroup(
602:                    ClassMetaData cmd) {
603:                int manyToManyCount = 0;
604:                FieldMetaData[] fields = cmd.fields;
605:                int n = fields.length;
606:                ArrayList a = new ArrayList(n);
607:                for (int i = 0; i < n; i++) {
608:                    FieldMetaData fmd = fields[i];
609:                    if (fmd.isManyToMany && fmd.managed || isReqField(cmd, fmd)) {
610:                        if (fmd.isManyToMany)
611:                            manyToManyCount++;
612:                        a.add(new FetchGroupField(fmd));
613:                    }
614:                }
615:                if (manyToManyCount == 0)
616:                    return null;
617:                FetchGroup g = new FetchGroup(cmd,
618:                        FetchGroup.MANY_TO_MANY_NAME, createStoreFetchGroup());
619:                g.fields = new FetchGroupField[a.size()];
620:                a.toArray(g.fields);
621:                return g;
622:            }
623:
624:            /**
625:             * Process the groups extension to find all of its fields. This does
626:             * not resolve next-fetch-group extensions as this can only be done
627:             * when all groups have been created.
628:             */
629:            private void processFetchGroupFields(ClassMetaData cmd,
630:                    FetchGroup g, boolean quite) {
631:                JdoExtension e = g.extension;
632:                HashSet fieldNameSet = new HashSet(17);
633:                ArrayList fields = new ArrayList();
634:                JdoExtension[] nested = e.nested;
635:                if (nested == null)
636:                    return;
637:                int nn = nested.length;
638:                boolean noFgFields = true;
639:                for (int k = 0; k < nn; k++) {
640:                    JdoExtension ne = nested[k];
641:                    if (ne.key != JdoExtensionKeys.FIELD_NAME)
642:                        continue;
643:                    String fname = ne.getString();
644:                    if (fieldNameSet.contains(fname)) {
645:                        throw BindingSupportImpl.getInstance().runtime(
646:                                "Field is already in group: '" + fname + "'\n"
647:                                        + ne.getContext());
648:                    }
649:                    noFgFields = false;
650:                    //don't add pk fields to fg's
651:                    FieldMetaData fmd = cmd.getFieldMetaData(fname);
652:                    if (fmd == null) {
653:                        cmd.addError(BindingSupportImpl.getInstance().runtime(
654:                                "Field does not exist: '" + fname + "'\n"
655:                                        + ne.getContext()), quite);
656:                        continue;
657:                    }
658:                    if (fmd.primaryKey)
659:                        continue;
660:                    //            if (fmd.jdbcField.isSharedWithPK()) continue;
661:
662:                    fieldNameSet.add(fname);
663:                    FetchGroupField f = new FetchGroupField(fmd);
664:                    f.extension = ne;
665:                    fields.add(f);
666:                }
667:
668:                //add the fields that should be in all the fg's
669:                FieldMetaData[] fmds = cmd.fields;
670:                int n = fmds.length;
671:                for (int i = 0; i < n; i++) {
672:                    FieldMetaData fmd = fmds[i];
673:                    if (!fmd.secondaryField && fmd.includeInAllFGs()
674:                            && !fieldNameSet.contains(fmd.name)) {
675:                        fieldNameSet.add(fmd.name);
676:                        FetchGroupField fgf = new FetchGroupField(fmd);
677:                        fields.add(fgf);
678:                    }
679:                }
680:
681:                int nf = fields.size();
682:                if (noFgFields && nf == 0) {
683:                    throw BindingSupportImpl.getInstance().runtime(
684:                            "Fetch group does not contain any fields: '"
685:                                    + g.name + "'\n" + e.getContext());
686:                }
687:                g.fields = new FetchGroupField[nf];
688:                fields.toArray(g.fields);
689:            }
690:
691:            /**
692:             * Process extensions for all fields in all groups. This resolves
693:             * next-fetch-group and next-key-fetch-group references.
694:             */
695:            private void processFetchGroups(ClassMetaData cmd) {
696:                processRefFetchGroup(cmd);
697:                FetchGroup[] groups = cmd.fetchGroups;
698:                if (groups == null) {
699:                    return;
700:                }
701:                FetchGroup dep = cmd.refFetchGroup;
702:                int ng = groups.length;
703:                for (int i = 0; i < ng; i++) {
704:                    FetchGroup group = groups[i];
705:                    if (group == dep)
706:                        continue;
707:                    FetchGroupField[] fields = group.fields;
708:                    if (fields == null)
709:                        continue;
710:                    int nf = fields.length;
711:                    for (int j = 0; j < nf; j++) {
712:                        FetchGroupField f = fields[j];
713:                        ClassMetaData refmd = f.fmd
714:                                .getRefOrValueClassMetaData();
715:                        ClassMetaData keymd = f.fmd.keyTypeMetaData;
716:                        JdoExtension[] nested = f.extension == null ? null
717:                                : f.extension.nested;
718:                        if (nested != null) {
719:                            int nl = nested.length;
720:                            for (int k = 0; k < nl; k++) {
721:                                JdoExtension e = nested[k];
722:                                switch (e.key) {
723:                                case JdoExtensionKeys.NEXT_FETCH_GROUP:
724:                                    processNextFetchGroup(f, e, refmd);
725:                                    break;
726:                                case JdoExtensionKeys.NEXT_KEY_FETCH_GROUP:
727:                                    processNextKeyFetchGroup(f, e, keymd);
728:                                    break;
729:                                default:
730:                                    if (e.isCommon()) {
731:                                        MetaDataBuilder
732:                                                .throwUnexpectedExtension(e);
733:                                    }
734:                                }
735:                                ;
736:                            }
737:                        }
738:                        if (f.nextFetchGroup == null && refmd != null
739:                                && refmd.fetchGroups != null) {
740:                            f.nextFetchGroup = refmd.fetchGroups[0];
741:                        }
742:                        if (f.nextKeyFetchGroup == null && keymd != null
743:                                && keymd.fetchGroups != null) {
744:                            f.nextKeyFetchGroup = keymd.fetchGroups[0];
745:                        }
746:                    }
747:                }
748:            }
749:
750:            private void processNextFetchGroup(FetchGroupField f,
751:                    JdoExtension e, ClassMetaData refmd) {
752:                if (f.nextFetchGroup != null) {
753:                    throw BindingSupportImpl.getInstance().runtime(
754:                            "Only one next-fetch-group extension is allowed\n"
755:                                    + e.getContext());
756:                }
757:                if (refmd == null) {
758:                    throw BindingSupportImpl.getInstance().runtime(
759:                            "Field does not reference a PC class\n"
760:                                    + e.getContext());
761:                }
762:                FetchGroup g = refmd.getFetchGroup(e.getString());
763:                if (g == null) {
764:                    throw BindingSupportImpl.getInstance().runtime(
765:                            "Fetch group '" + e.getString()
766:                                    + "' not found in class " + refmd.qname
767:                                    + "\n" + e.getContext());
768:                }
769:                f.nextFetchGroup = g;
770:            }
771:
772:            private void processNextKeyFetchGroup(FetchGroupField f,
773:                    JdoExtension e, ClassMetaData keymd) {
774:                if (f.nextKeyFetchGroup != null) {
775:                    throw BindingSupportImpl.getInstance().runtime(
776:                            "Only one next-key-fetch-group extension is allowed\n"
777:                                    + e.getContext());
778:                }
779:                if (keymd == null) {
780:                    throw BindingSupportImpl.getInstance().runtime(
781:                            "Field key does not reference a PC class\n"
782:                                    + e.getContext());
783:                }
784:                FetchGroup g = keymd.getFetchGroup(e.getString());
785:                if (g == null) {
786:                    throw BindingSupportImpl.getInstance().runtime(
787:                            "Fetch group '" + e.getString()
788:                                    + "' not found in class " + keymd.qname
789:                                    + "\n" + e.getContext());
790:                }
791:                f.nextKeyFetchGroup = g;
792:            }
793:
794:            /**
795:             * Fill in the nextFetchGroup and nextKeyFetchGroup references for
796:             * all the fields in the refFetchGroup for cmd (if any). Only dependent
797:             * object references are followed.
798:             */
799:            private void processRefFetchGroup(ClassMetaData cmd) {
800:                FetchGroup g = cmd.refFetchGroup;
801:                if (g == null)
802:                    return;
803:                FetchGroupField[] fields = g.fields;
804:                int nf = fields.length;
805:                for (int j = 0; j < nf; j++) {
806:                    FetchGroupField f = fields[j];
807:                    FieldMetaData fmd = f.fmd;
808:                    // only follow dependent object references for this group
809:                    if (fmd.dependentValues) {
810:                        ClassMetaData refmd = fmd.getRefOrValueClassMetaData();
811:                        if (refmd != null)
812:                            f.nextFetchGroup = refmd.refFetchGroup;
813:                    }
814:                    if (fmd.dependentKeys) {
815:                        ClassMetaData keymd = fmd.keyTypeMetaData;
816:                        if (keymd != null)
817:                            f.nextKeyFetchGroup = keymd.refFetchGroup;
818:                    }
819:                }
820:            }
821:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.