/** Whether our configuration state includes the given field. */ private boolean includes(FieldMetaData fmd) { if ((hasFetchGroupDefault() && fmd.isInDefaultFetchGroup()) || hasFetchGroupAll() || hasField(fmd.getFullName(false)) || hasExtendedLookupPath(fmd)) return true; String[] fgs = fmd.getCustomFetchGroups(); for (int i = 0; i < fgs.length; i++) if (hasFetchGroup(fgs[i])) return true; return false; }
public int requiresFetch(FieldMetaData fm) { if (!includes(fm)) return FETCH_NONE; Class<?> type = fm.getRelationType(); if (type == null) return FETCH_LOAD; if (_availableDepth == 0) return FETCH_NONE; // we can skip calculating recursion depth if this is a top-level conf: // the field is in our fetch groups, so can't possibly not select if (_parent == null) return FETCH_LOAD; String fieldName = fm.getFullName(false); int rdepth = getAvailableRecursionDepth(fm, type, fieldName, false); if (rdepth != FetchGroup.DEPTH_INFINITE && rdepth <= 0) return FETCH_NONE; if (StringUtils.equals(_directRelationOwner, fieldName)) return FETCH_REF; return FETCH_LOAD; }
/** * 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); }
public FetchConfiguration traverse(FieldMetaData fm) { Class<?> type = fm.getRelationType(); if (type == null) return this; FetchConfigurationImpl clone = newInstance(_state); clone._parent = this; clone._availableDepth = reduce(_availableDepth); clone._fromField = fm.getFullName(false); clone._fromType = type; clone._availableRecursion = getAvailableRecursionDepth(fm, type, fm.getFullName(false), true); if (StringUtils.equals(_directRelationOwner, fm.getFullName(false))) clone._load = false; else clone._load = _load; FieldMetaData owner = fm.getMappedByMetaData(); if (owner != null && owner.getTypeCode() == JavaTypes.PC) clone._directRelationOwner = owner.getFullName(false); return clone; }
private boolean hasExtendedLookupPath(FieldMetaData fmd) { return getExtendedPathLookup() && (hasField(fmd.getRealName()) || (_fromField != null && hasField(_fromField + "." + fmd.getName()))); }