public Iterator<T> iterator() { _broker.assertNontransactionalRead(); CloseableIterator citr = null; try { // create an iterator chain; add pnew objects if transactional CloseableIteratorChain chain = new CloseableIteratorChain(); boolean trans = !_ignore && _broker.isActive(); if (trans) chain.addIterator(new FilterNewIterator()); // add database iterators for each implementing class MetaDataRepository repos = _broker.getConfiguration().getMetaDataRepositoryInstance(); ClassMetaData meta = repos.getMetaData(_type, _broker.getClassLoader(), false); ClassMetaData[] metas; if (meta != null && (!_subs || !meta.isManagedInterface()) && (meta.isMapped() || (_subs && meta.getMappedPCSubclassMetaDatas().length > 0))) metas = new ClassMetaData[] {meta}; else if (_subs && (meta == null || meta.isManagedInterface())) metas = repos.getImplementorMetaDatas(_type, _broker.getClassLoader(), false); else metas = EMPTY_METAS; ResultObjectProvider rop; for (int i = 0; i < metas.length; i++) { rop = _broker.getStoreManager().executeExtent(metas[i], _subs, _fc); if (rop != null) chain.addIterator(new ResultObjectProviderIterator(rop)); } // filter deleted objects if transactional if (trans) citr = new FilterDeletedIterator(chain); else citr = chain; citr.setRemoveOnClose(this); } catch (OpenJPAException ke) { throw ke; } catch (RuntimeException re) { throw new GeneralException(re); } lock(); try { if (_openItrs == null) _openItrs = new ReferenceHashSet(ReferenceHashSet.WEAK); _openItrs.add(citr); } finally { unlock(); } return citr; }
/** * Return the available recursion depth via the given field for the given type. * * @param traverse whether we're traversing the field */ private int getAvailableRecursionDepth( FieldMetaData fm, Class<?> type, String fromField, boolean traverse) { // see if there's a previous limit int avail = Integer.MIN_VALUE; for (FetchConfigurationImpl f = this; f != null; f = f._parent) { if (StringUtils.equals(f._fromField, fromField) && ImplHelper.isAssignable(f._fromType, type)) { avail = f._availableRecursion; if (traverse) avail = reduce(avail); break; } } if (avail == 0) return 0; // calculate fetch groups max ClassMetaData meta = fm.getDefiningMetaData(); int max = Integer.MIN_VALUE; if (fm.isInDefaultFetchGroup()) max = meta.getFetchGroup(FetchGroup.NAME_DEFAULT).getRecursionDepth(fm); String[] groups = fm.getCustomFetchGroups(); int cur; for (int i = 0; max != FetchGroup.DEPTH_INFINITE && i < groups.length; i++) { // ignore custom groups that are inactive in this configuration if (!this.hasFetchGroup(groups[i])) continue; cur = meta.getFetchGroup(groups[i]).getRecursionDepth(fm); if (cur == FetchGroup.DEPTH_INFINITE || cur > max) max = cur; } // reduce max if we're traversing a self-type relation if (traverse && max != Integer.MIN_VALUE && ImplHelper.isAssignable(meta.getDescribedType(), type)) max = reduce(max); // take min/defined of previous avail and fetch group max if (avail == Integer.MIN_VALUE && max == Integer.MIN_VALUE) { int def = FetchGroup.RECURSION_DEPTH_DEFAULT; return (traverse && ImplHelper.isAssignable(meta.getDescribedType(), type)) ? def - 1 : def; } if (avail == Integer.MIN_VALUE || avail == FetchGroup.DEPTH_INFINITE) return max; if (max == Integer.MIN_VALUE || max == FetchGroup.DEPTH_INFINITE) return avail; return Math.min(max, avail); }
/** * Return the least-derived metadata in the inheritance chain above <code>meta</code>, or <code> * meta</code> if it is a least-derived metadata. */ private static ClassMetaData getLeastDerived(ClassMetaData meta) { while (meta.getPCSuperclass() != null) meta = meta.getPCSuperclassMetaData(); return meta; }