Source Code Cross Referenced for FetchConfigurationImpl.java in  » Database-ORM » openjpa » org » apache » openjpa » kernel » 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 » openjpa » org.apache.openjpa.kernel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        package org.apache.openjpa.kernel;
020:
021:        import java.io.Serializable;
022:        import java.util.ArrayList;
023:        import java.util.Arrays;
024:        import java.util.Collection;
025:        import java.util.Collections;
026:        import java.util.HashMap;
027:        import java.util.HashSet;
028:        import java.util.Iterator;
029:        import java.util.List;
030:        import java.util.Map;
031:        import java.util.Set;
032:
033:        import org.apache.commons.lang.StringUtils;
034:        import org.apache.openjpa.conf.OpenJPAConfiguration;
035:        import org.apache.openjpa.lib.rop.EagerResultList;
036:        import org.apache.openjpa.lib.rop.ListResultObjectProvider;
037:        import org.apache.openjpa.lib.rop.ResultList;
038:        import org.apache.openjpa.lib.rop.ResultObjectProvider;
039:        import org.apache.openjpa.lib.rop.SimpleResultList;
040:        import org.apache.openjpa.lib.rop.WindowResultList;
041:        import org.apache.openjpa.lib.util.Localizer;
042:        import org.apache.openjpa.meta.ClassMetaData;
043:        import org.apache.openjpa.meta.FetchGroup;
044:        import org.apache.openjpa.meta.FieldMetaData;
045:        import org.apache.openjpa.meta.JavaTypes;
046:        import org.apache.openjpa.util.ImplHelper;
047:        import org.apache.openjpa.util.InternalException;
048:        import org.apache.openjpa.util.NoTransactionException;
049:        import org.apache.openjpa.util.UserException;
050:
051:        /**
052:         * Allows configuration and optimization of how objects are loaded from
053:         * the data store.
054:         *
055:         * @since 0.3.0
056:         * @author Abe White
057:         * @author Pinaki Poddar
058:         * @nojavadoc
059:         */
060:        public class FetchConfigurationImpl implements  FetchConfiguration,
061:                Cloneable {
062:
063:            private static final Localizer _loc = Localizer
064:                    .forPackage(FetchConfigurationImpl.class);
065:
066:            /**
067:             * Configurable state shared throughout a traversal chain.
068:             */
069:            protected static class ConfigurationState implements  Serializable {
070:                public transient StoreContext ctx = null;
071:                public int fetchBatchSize = 0;
072:                public int maxFetchDepth = 1;
073:                public boolean queryCache = true;
074:                public int flushQuery = 0;
075:                public int lockTimeout = -1;
076:                public int readLockLevel = LOCK_NONE;
077:                public int writeLockLevel = LOCK_NONE;
078:                public Set fetchGroups = null;
079:                public Set fields = null;
080:                public Set rootClasses;
081:                public Set rootInstances;
082:                public Map hints = null;
083:            }
084:
085:            private final ConfigurationState _state;
086:            private FetchConfigurationImpl _parent;
087:            private String _fromField;
088:            private Class _fromType;
089:            private String _directRelationOwner;
090:            private boolean _load = true;
091:            private int _availableRecursion;
092:            private int _availableDepth;
093:
094:            public FetchConfigurationImpl() {
095:                this (null);
096:            }
097:
098:            protected FetchConfigurationImpl(ConfigurationState state) {
099:                _state = (state == null) ? new ConfigurationState() : state;
100:                _availableDepth = _state.maxFetchDepth;
101:            }
102:
103:            public StoreContext getContext() {
104:                return _state.ctx;
105:            }
106:
107:            public void setContext(StoreContext ctx) {
108:                // can't reset non-null context to another context
109:                if (ctx != null && _state.ctx != null && ctx != _state.ctx)
110:                    throw new InternalException();
111:                _state.ctx = ctx;
112:                if (ctx == null)
113:                    return;
114:
115:                // initialize to conf info
116:                OpenJPAConfiguration conf = ctx.getConfiguration();
117:                setFetchBatchSize(conf.getFetchBatchSize());
118:                setFlushBeforeQueries(conf.getFlushBeforeQueriesConstant());
119:                setLockTimeout(conf.getLockTimeout());
120:                clearFetchGroups();
121:                addFetchGroups(Arrays.asList(conf.getFetchGroupsList()));
122:                setMaxFetchDepth(conf.getMaxFetchDepth());
123:            }
124:
125:            /**
126:             * Clone this instance.
127:             */
128:            public Object clone() {
129:                FetchConfigurationImpl clone = newInstance(null);
130:                clone._state.ctx = _state.ctx;
131:                clone._parent = _parent;
132:                clone._fromField = _fromField;
133:                clone._fromType = _fromType;
134:                clone._directRelationOwner = _directRelationOwner;
135:                clone._load = _load;
136:                clone._availableRecursion = _availableRecursion;
137:                clone._availableDepth = _availableDepth;
138:                clone.copy(this );
139:                return clone;
140:            }
141:
142:            /**
143:             * Return a new hollow instance.
144:             */
145:            protected FetchConfigurationImpl newInstance(
146:                    ConfigurationState state) {
147:                return new FetchConfigurationImpl(state);
148:            }
149:
150:            public void copy(FetchConfiguration fetch) {
151:                setFetchBatchSize(fetch.getFetchBatchSize());
152:                setMaxFetchDepth(fetch.getMaxFetchDepth());
153:                setQueryCacheEnabled(fetch.getQueryCacheEnabled());
154:                setFlushBeforeQueries(fetch.getFlushBeforeQueries());
155:                setLockTimeout(fetch.getLockTimeout());
156:                clearFetchGroups();
157:                addFetchGroups(fetch.getFetchGroups());
158:                clearFields();
159:                addFields(fetch.getFields());
160:
161:                // don't use setters because require active transaction
162:                _state.readLockLevel = fetch.getReadLockLevel();
163:                _state.writeLockLevel = fetch.getWriteLockLevel();
164:            }
165:
166:            public int getFetchBatchSize() {
167:                return _state.fetchBatchSize;
168:            }
169:
170:            public FetchConfiguration setFetchBatchSize(int fetchBatchSize) {
171:                if (fetchBatchSize == DEFAULT && _state.ctx != null)
172:                    fetchBatchSize = _state.ctx.getConfiguration()
173:                            .getFetchBatchSize();
174:                if (fetchBatchSize != DEFAULT)
175:                    _state.fetchBatchSize = fetchBatchSize;
176:                return this ;
177:            }
178:
179:            public int getMaxFetchDepth() {
180:                return _state.maxFetchDepth;
181:            }
182:
183:            public FetchConfiguration setMaxFetchDepth(int depth) {
184:                if (depth == DEFAULT && _state.ctx != null)
185:                    depth = _state.ctx.getConfiguration().getMaxFetchDepth();
186:                if (depth != DEFAULT) {
187:                    _state.maxFetchDepth = depth;
188:                    if (_parent == null)
189:                        _availableDepth = depth;
190:                }
191:                return this ;
192:            }
193:
194:            public boolean getQueryCacheEnabled() {
195:                return _state.queryCache;
196:            }
197:
198:            public FetchConfiguration setQueryCacheEnabled(boolean cache) {
199:                _state.queryCache = cache;
200:                return this ;
201:            }
202:
203:            public int getFlushBeforeQueries() {
204:                return _state.flushQuery;
205:            }
206:
207:            public FetchConfiguration setFlushBeforeQueries(int flush) {
208:                if (flush == DEFAULT && _state.ctx != null)
209:                    _state.flushQuery = _state.ctx.getConfiguration()
210:                            .getFlushBeforeQueriesConstant();
211:                else if (flush != DEFAULT)
212:                    _state.flushQuery = flush;
213:                return this ;
214:            }
215:
216:            public Set getFetchGroups() {
217:                return (_state.fetchGroups == null) ? Collections.EMPTY_SET
218:                        : _state.fetchGroups;
219:            }
220:
221:            public boolean hasFetchGroup(String group) {
222:                return _state.fetchGroups != null
223:                        && (_state.fetchGroups.contains(group) || _state.fetchGroups
224:                                .contains(FetchGroup.NAME_ALL));
225:            }
226:
227:            public FetchConfiguration addFetchGroup(String name) {
228:                if (StringUtils.isEmpty(name))
229:                    throw new UserException(_loc.get("null-fg"));
230:
231:                lock();
232:                try {
233:                    if (_state.fetchGroups == null)
234:                        _state.fetchGroups = new HashSet();
235:                    _state.fetchGroups.add(name);
236:                } finally {
237:                    unlock();
238:                }
239:                return this ;
240:            }
241:
242:            public FetchConfiguration addFetchGroups(Collection groups) {
243:                if (groups == null || groups.isEmpty())
244:                    return this ;
245:                for (Iterator itr = groups.iterator(); itr.hasNext();)
246:                    addFetchGroup((String) itr.next());
247:                return this ;
248:            }
249:
250:            public FetchConfiguration removeFetchGroup(String group) {
251:                lock();
252:                try {
253:                    if (_state.fetchGroups != null)
254:                        _state.fetchGroups.remove(group);
255:                } finally {
256:                    unlock();
257:                }
258:                return this ;
259:            }
260:
261:            public FetchConfiguration removeFetchGroups(Collection groups) {
262:                lock();
263:                try {
264:                    if (_state.fetchGroups != null)
265:                        _state.fetchGroups.removeAll(groups);
266:                } finally {
267:                    unlock();
268:                }
269:                return this ;
270:            }
271:
272:            public FetchConfiguration clearFetchGroups() {
273:                lock();
274:                try {
275:                    if (_state.fetchGroups != null)
276:                        _state.fetchGroups.clear();
277:                } finally {
278:                    unlock();
279:                }
280:                return this ;
281:            }
282:
283:            public FetchConfiguration resetFetchGroups() {
284:                clearFetchGroups();
285:                if (_state.ctx != null)
286:                    addFetchGroups(Arrays.asList(_state.ctx.getConfiguration()
287:                            .getFetchGroupsList()));
288:                return this ;
289:            }
290:
291:            public Set getFields() {
292:                return (_state.fields == null) ? Collections.EMPTY_SET
293:                        : _state.fields;
294:            }
295:
296:            public boolean hasField(String field) {
297:                return _state.fields != null && _state.fields.contains(field);
298:            }
299:
300:            public FetchConfiguration addField(String field) {
301:                if (StringUtils.isEmpty(field))
302:                    throw new UserException(_loc.get("null-field"));
303:
304:                lock();
305:                try {
306:                    if (_state.fields == null)
307:                        _state.fields = new HashSet();
308:                    _state.fields.add(field);
309:                } finally {
310:                    unlock();
311:                }
312:                return this ;
313:            }
314:
315:            public FetchConfiguration addFields(Collection fields) {
316:                if (fields == null || fields.isEmpty())
317:                    return this ;
318:
319:                lock();
320:                try {
321:                    if (_state.fields == null)
322:                        _state.fields = new HashSet();
323:                    _state.fields.addAll(fields);
324:                } finally {
325:                    unlock();
326:                }
327:                return this ;
328:            }
329:
330:            public FetchConfiguration removeField(String field) {
331:                lock();
332:                try {
333:                    if (_state.fields != null)
334:                        _state.fields.remove(field);
335:                } finally {
336:                    unlock();
337:                }
338:                return this ;
339:            }
340:
341:            public FetchConfiguration removeFields(Collection fields) {
342:                lock();
343:                try {
344:                    if (_state.fields != null)
345:                        _state.fields.removeAll(fields);
346:                } finally {
347:                    unlock();
348:                }
349:                return this ;
350:            }
351:
352:            public FetchConfiguration clearFields() {
353:                lock();
354:                try {
355:                    if (_state.fields != null)
356:                        _state.fields.clear();
357:                } finally {
358:                    unlock();
359:                }
360:                return this ;
361:            }
362:
363:            public int getLockTimeout() {
364:                return _state.lockTimeout;
365:            }
366:
367:            public FetchConfiguration setLockTimeout(int timeout) {
368:                if (timeout == DEFAULT && _state.ctx != null)
369:                    _state.lockTimeout = _state.ctx.getConfiguration()
370:                            .getLockTimeout();
371:                else if (timeout != DEFAULT)
372:                    _state.lockTimeout = timeout;
373:                return this ;
374:            }
375:
376:            public int getReadLockLevel() {
377:                return _state.readLockLevel;
378:            }
379:
380:            public FetchConfiguration setReadLockLevel(int level) {
381:                if (_state.ctx == null)
382:                    return this ;
383:
384:                lock();
385:                try {
386:                    assertActiveTransaction();
387:                    if (level == DEFAULT)
388:                        _state.readLockLevel = _state.ctx.getConfiguration()
389:                                .getReadLockLevelConstant();
390:                    else
391:                        _state.readLockLevel = level;
392:                } finally {
393:                    unlock();
394:                }
395:                return this ;
396:            }
397:
398:            public int getWriteLockLevel() {
399:                return _state.writeLockLevel;
400:            }
401:
402:            public FetchConfiguration setWriteLockLevel(int level) {
403:                if (_state.ctx == null)
404:                    return this ;
405:
406:                lock();
407:                try {
408:                    assertActiveTransaction();
409:                    if (level == DEFAULT)
410:                        _state.writeLockLevel = _state.ctx.getConfiguration()
411:                                .getWriteLockLevelConstant();
412:                    else
413:                        _state.writeLockLevel = level;
414:                } finally {
415:                    unlock();
416:                }
417:                return this ;
418:            }
419:
420:            public ResultList newResultList(ResultObjectProvider rop) {
421:                if (rop instanceof  ListResultObjectProvider)
422:                    return new SimpleResultList(rop);
423:                if (_state.fetchBatchSize < 0)
424:                    return new EagerResultList(rop);
425:                if (rop.supportsRandomAccess())
426:                    return new SimpleResultList(rop);
427:                return new WindowResultList(rop);
428:            }
429:
430:            /**
431:             * Throw an exception if no transaction is active.
432:             */
433:            private void assertActiveTransaction() {
434:                if (_state.ctx != null && !_state.ctx.isActive())
435:                    throw new NoTransactionException(_loc.get("not-active"));
436:            }
437:
438:            public void setHint(String name, Object value) {
439:                lock();
440:                try {
441:                    if (_state.hints == null)
442:                        _state.hints = new HashMap();
443:                    _state.hints.put(name, value);
444:                } finally {
445:                    unlock();
446:                }
447:            }
448:
449:            public Object getHint(String name) {
450:                return (_state.hints == null) ? null : _state.hints.get(name);
451:            }
452:
453:            public Set getRootClasses() {
454:                return (_state.rootClasses == null) ? Collections.EMPTY_SET
455:                        : _state.rootClasses;
456:            }
457:
458:            public FetchConfiguration setRootClasses(Collection classes) {
459:                lock();
460:                try {
461:                    if (_state.rootClasses != null)
462:                        _state.rootClasses.clear();
463:                    if (classes != null && !classes.isEmpty()) {
464:                        if (_state.rootClasses == null)
465:                            _state.rootClasses = new HashSet(classes);
466:                        else
467:                            _state.rootClasses.addAll(classes);
468:                    }
469:                } finally {
470:                    unlock();
471:                }
472:                return this ;
473:            }
474:
475:            public Set getRootInstances() {
476:                return (_state.rootInstances == null) ? Collections.EMPTY_SET
477:                        : _state.rootInstances;
478:            }
479:
480:            public FetchConfiguration setRootInstances(Collection instances) {
481:                lock();
482:                try {
483:                    if (_state.rootInstances != null)
484:                        _state.rootInstances.clear();
485:                    if (instances != null && !instances.isEmpty()) {
486:                        if (_state.rootInstances == null)
487:                            _state.rootInstances = new HashSet(instances);
488:                        else
489:                            _state.rootInstances.addAll(instances);
490:                    }
491:                } finally {
492:                    unlock();
493:                }
494:                return this ;
495:            }
496:
497:            public void lock() {
498:                if (_state.ctx != null)
499:                    _state.ctx.lock();
500:            }
501:
502:            public void unlock() {
503:                if (_state.ctx != null)
504:                    _state.ctx.unlock();
505:            }
506:
507:            /////////////
508:            // Traversal
509:            /////////////
510:
511:            public int requiresFetch(FieldMetaData fm) {
512:                if (!includes(fm))
513:                    return FETCH_NONE;
514:
515:                Class type = getRelationType(fm);
516:                if (type == null)
517:                    return FETCH_LOAD;
518:                if (_availableDepth == 0)
519:                    return FETCH_NONE;
520:
521:                // we can skip calculating recursion depth if this is a top-level conf:
522:                // the field is in our fetch groups, so can't possibly not select
523:                if (_parent == null)
524:                    return FETCH_LOAD;
525:
526:                int rdepth = getAvailableRecursionDepth(fm, type, false);
527:                if (rdepth != FetchGroup.DEPTH_INFINITE && rdepth <= 0)
528:                    return FETCH_NONE;
529:
530:                if (StringUtils.equals(_directRelationOwner, fm.getFullName()))
531:                    return FETCH_REF;
532:                return FETCH_LOAD;
533:            }
534:
535:            public boolean requiresLoad() {
536:                return _load;
537:            }
538:
539:            public FetchConfiguration traverse(FieldMetaData fm) {
540:                Class type = getRelationType(fm);
541:                if (type == null)
542:                    return this ;
543:
544:                FetchConfigurationImpl clone = newInstance(_state);
545:                clone._parent = this ;
546:                clone._availableDepth = reduce(_availableDepth);
547:                clone._fromField = fm.getFullName(false);
548:                clone._fromType = type;
549:                clone._availableRecursion = getAvailableRecursionDepth(fm,
550:                        type, true);
551:                if (StringUtils.equals(_directRelationOwner, fm.getFullName()))
552:                    clone._load = false;
553:                else
554:                    clone._load = _load;
555:
556:                FieldMetaData owner = fm.getMappedByMetaData();
557:                if (owner != null && owner.getTypeCode() == JavaTypes.PC)
558:                    clone._directRelationOwner = owner.getFullName();
559:
560:                return clone;
561:            }
562:
563:            /**
564:             * Whether our configuration state includes the given field.
565:             */
566:            private boolean includes(FieldMetaData fmd) {
567:                if ((fmd.isInDefaultFetchGroup() && hasFetchGroup(FetchGroup.NAME_DEFAULT))
568:                        || hasFetchGroup(FetchGroup.NAME_ALL)
569:                        || hasField(fmd.getFullName(false)))
570:                    return true;
571:                String[] fgs = fmd.getCustomFetchGroups();
572:                for (int i = 0; i < fgs.length; i++)
573:                    if (hasFetchGroup(fgs[i]))
574:                        return true;
575:                return false;
576:            }
577:
578:            /**
579:             * Return the available recursion depth via the given field for the
580:             * given type.
581:             *
582:             * @param traverse whether we're traversing the field
583:             */
584:            private int getAvailableRecursionDepth(FieldMetaData fm,
585:                    Class type, boolean traverse) {
586:                // see if there's a previous limit
587:                int avail = Integer.MIN_VALUE;
588:                for (FetchConfigurationImpl f = this ; f != null; f = f._parent) {
589:                    if (ImplHelper.isAssignable(f._fromType, type)) {
590:                        avail = f._availableRecursion;
591:                        if (traverse)
592:                            avail = reduce(avail);
593:                        break;
594:                    }
595:                }
596:                if (avail == 0)
597:                    return 0;
598:
599:                // calculate fetch groups max
600:                ClassMetaData meta = fm.getDefiningMetaData();
601:                int max = Integer.MIN_VALUE;
602:                if (fm.isInDefaultFetchGroup())
603:                    max = meta.getFetchGroup(FetchGroup.NAME_DEFAULT)
604:                            .getRecursionDepth(fm);
605:                String[] groups = fm.getCustomFetchGroups();
606:                int cur;
607:                for (int i = 0; max != FetchGroup.DEPTH_INFINITE
608:                        && i < groups.length; i++) {
609:                    // ignore custom groups that are inactive in this configuration
610:                    if (!this .hasFetchGroup(groups[i]))
611:                        continue;
612:                    cur = meta.getFetchGroup(groups[i]).getRecursionDepth(fm);
613:                    if (cur == FetchGroup.DEPTH_INFINITE || cur > max)
614:                        max = cur;
615:                }
616:                // reduce max if we're traversing a self-type relation
617:                if (traverse
618:                        && max != Integer.MIN_VALUE
619:                        && ImplHelper.isAssignable(meta.getDescribedType(),
620:                                type))
621:                    max = reduce(max);
622:
623:                // take min/defined of previous avail and fetch group max
624:                if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) {
625:                    int def = FetchGroup.RECURSION_DEPTH_DEFAULT;
626:                    return (traverse && ImplHelper.isAssignable(meta
627:                            .getDescribedType(), type)) ? def - 1 : def;
628:                }
629:                if (avail == Integer.MIN_VALUE
630:                        || avail == FetchGroup.DEPTH_INFINITE)
631:                    return max;
632:                if (max == Integer.MIN_VALUE
633:                        || max == FetchGroup.DEPTH_INFINITE)
634:                    return avail;
635:                return Math.min(max, avail);
636:            }
637:
638:            /**
639:             * Return the relation type of the given field.
640:             */
641:            private static Class getRelationType(FieldMetaData fm) {
642:                if (fm.isDeclaredTypePC())
643:                    return fm.getDeclaredType();
644:                if (fm.getElement().isDeclaredTypePC())
645:                    return fm.getElement().getDeclaredType();
646:                if (fm.getKey().isDeclaredTypePC())
647:                    return fm.getKey().getDeclaredType();
648:                return null;
649:            }
650:
651:            /**
652:             * Reduce the given logical depth by 1.
653:             */
654:            private static int reduce(int d) {
655:                if (d == 0)
656:                    return 0;
657:                if (d != FetchGroup.DEPTH_INFINITE)
658:                    d--;
659:                return d;
660:            }
661:
662:            /////////////////
663:            // Debug methods
664:            /////////////////
665:
666:            FetchConfiguration getParent() {
667:                return _parent;
668:            }
669:
670:            boolean isRoot() {
671:                return _parent == null;
672:            }
673:
674:            FetchConfiguration getRoot() {
675:                return (isRoot()) ? this  : _parent.getRoot();
676:            }
677:
678:            int getAvailableFetchDepth() {
679:                return _availableDepth;
680:            }
681:
682:            int getAvailableRecursionDepth() {
683:                return _availableRecursion;
684:            }
685:
686:            String getTraversedFromField() {
687:                return _fromField;
688:            }
689:
690:            Class getTraversedFromType() {
691:                return _fromType;
692:            }
693:
694:            List getPath() {
695:                if (isRoot())
696:                    return Collections.EMPTY_LIST;
697:                return trackPath(new ArrayList());
698:            }
699:
700:            List trackPath(List path) {
701:                if (_parent != null)
702:                    _parent.trackPath(path);
703:                path.add(this );
704:                return path;
705:            }
706:
707:            public String toString() {
708:                return "FetchConfiguration@" + System.identityHashCode(this )
709:                        + " (" + _availableDepth + ")" + getPathString();
710:            }
711:
712:            private String getPathString() {
713:                List path = getPath();
714:                if (path.isEmpty())
715:                    return "";
716:                StringBuffer buf = new StringBuffer().append(": ");
717:                for (Iterator itr = path.iterator(); itr.hasNext();) {
718:                    buf.append(((FetchConfigurationImpl) itr.next())
719:                            .getTraversedFromField());
720:                    if (itr.hasNext())
721:                        buf.append("->");
722:                }
723:                return buf.toString();
724:            }
725:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.