Beispiel #1
0
  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);
  }
Beispiel #3
0
 /**
  * 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;
 }