All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.avaje.ebean.common.AbstractBeanCollection Maven / Gradle / Ivy

The newest version!
package com.avaje.ebean.common;

import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import javax.persistence.PersistenceException;

import com.avaje.ebean.Ebean;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.BeanCollectionTouched;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;

/**
 * Base class for List Set and Map implementations of BeanCollection.
 * 
 * @author rbygrave
 */
public abstract class AbstractBeanCollection implements BeanCollection {

  private static final long serialVersionUID = 3365725236140187588L;

  protected boolean readOnly;

  /**
   * The EbeanServer this is associated with. (used for lazy fetch).
   */
  protected transient BeanCollectionLoader loader;

  protected transient ExpressionList filterMany;

  protected int loaderIndex;

  protected String ebeanServerName;

  protected transient BeanCollectionTouched beanCollectionTouched;

  protected transient Future fetchFuture;

  /**
   * The owning bean (used for lazy fetch).
   */
  protected final Object ownerBean;

  /**
   * The name of this property in the owning bean (used for lazy fetch).
   */
  protected final String propertyName;

  /**
   * Can be false when a background thread is used to continue the fetch the
   * rows. It will set this to true when it is finished. If no background thread
   * is used then this should already be true.
   */
  protected boolean finishedFetch = true;

  /**
   * Flag set to true if rows are limited by firstRow maxRows and more rows
   * exist. For use by client to enable 'next' for paging.
   */
  protected boolean hasMoreRows;

  protected ModifyHolder modifyHolder;

  protected ModifyListenMode modifyListenMode;
  protected boolean modifyAddListening;
  protected boolean modifyRemoveListening;
  protected boolean modifyListening;

  /**
   * Constructor not non-lazy loading collection.
   */
  public AbstractBeanCollection() {
    this.ownerBean = null;
    this.propertyName = null;
  }

  /**
   * Used to create deferred fetch proxy.
   */
  public AbstractBeanCollection(BeanCollectionLoader loader, Object ownerBean, String propertyName) {
    this.loader = loader;
    this.ebeanServerName = loader.getName();
    this.ownerBean = ownerBean;
    this.propertyName = propertyName;

    if (ownerBean instanceof EntityBean) {
      EntityBeanIntercept ebi = ((EntityBean) ownerBean)._ebean_getIntercept();
      this.readOnly = ebi.isReadOnly();
    }
  }

  public Object getOwnerBean() {
    return ownerBean;
  }

  public String getPropertyName() {
    return propertyName;
  }

  public int getLoaderIndex() {
    return loaderIndex;
  }

  public ExpressionList getFilterMany() {
    return filterMany;
  }

  public void setFilterMany(ExpressionList filterMany) {
    this.filterMany = filterMany;
  }

  protected void lazyLoadCollection(boolean onlyIds) {
    if (loader == null) {
      loader = (BeanCollectionLoader) Ebean.getServer(ebeanServerName);
    }
    if (loader == null) {
      String msg = "Lazy loading but LazyLoadEbeanServer is null?"
          + " The LazyLoadEbeanServer needs to be set after deserialization"
          + " to support lazy loading.";
      throw new PersistenceException(msg);
    }

    loader.loadMany(this, onlyIds);
    checkEmptyLazyLoad();
  }

  protected void touched() {
    if (beanCollectionTouched != null) {
      // only call this once
      beanCollectionTouched.notifyTouched(this);
      beanCollectionTouched = null;
    }
  }

  public void setBeanCollectionTouched(BeanCollectionTouched notify) {
    this.beanCollectionTouched = notify;
  }

  public void setLoader(int beanLoaderIndex, BeanCollectionLoader loader) {
    this.loaderIndex = beanLoaderIndex;
    this.loader = loader;
    this.ebeanServerName = loader.getName();
  }

  public boolean isReadOnly() {
    return readOnly;
  }

  public void setReadOnly(boolean readOnly) {
    this.readOnly = readOnly;
  }

  /**
   * Set to true if maxRows was hit and there are actually more rows available.
   * 

* Can be used by client code that is paging through results using * setFirstRow() setMaxRows(). If this returns true then the client can * display a 'next' button etc. *

*/ public boolean hasMoreRows() { return hasMoreRows; } /** * Set to true when maxRows is hit but there are actually more rows available. * This is set so that client code knows that there is more data available. */ public void setHasMoreRows(boolean hasMoreRows) { this.hasMoreRows = hasMoreRows; } /** * Returns true if the fetch has finished. False if the fetch is continuing in * a background thread. */ public boolean isFinishedFetch() { return finishedFetch; } /** * Set to true when a fetch has finished. Used when a fetch continues in the * background. */ public void setFinishedFetch(boolean finishedFetch) { this.finishedFetch = finishedFetch; } public void setBackgroundFetch(Future fetchFuture) { this.fetchFuture = fetchFuture; } public void backgroundFetchWait(long wait, TimeUnit timeUnit) { if (fetchFuture != null) { try { fetchFuture.get(wait, timeUnit); } catch (Exception e) { throw new PersistenceException(e); } } } public void backgroundFetchWait() { if (fetchFuture != null) { try { fetchFuture.get(); } catch (Exception e) { throw new PersistenceException(e); } } } protected void checkReadOnly() { if (readOnly) { String msg = "This collection is in ReadOnly mode"; throw new IllegalStateException(msg); } } // --------------------------------------------------------- // Support for modify additions deletions etc - ManyToMany // --------------------------------------------------------- /** * set modifyListening to be on or off. */ public void setModifyListening(ModifyListenMode mode) { this.modifyListenMode = mode; this.modifyAddListening = ModifyListenMode.ALL.equals(mode); this.modifyRemoveListening = modifyAddListening || ModifyListenMode.REMOVALS.equals(mode); this.modifyListening = modifyRemoveListening || modifyAddListening; if (modifyListening) { // lose any existing modifications modifyHolder = null; } } /** * Return the modify listening mode this collection is using. */ public ModifyListenMode getModifyListenMode() { return modifyListenMode; } protected ModifyHolder getModifyHolder() { if (modifyHolder == null) { modifyHolder = new ModifyHolder(); } return modifyHolder; } public void modifyAddition(E bean) { if (modifyAddListening) { getModifyHolder().modifyAddition(bean); } } public void modifyRemoval(Object bean) { if (modifyRemoveListening) { getModifyHolder().modifyRemoval(bean); } } public void modifyReset() { if (modifyHolder != null) { modifyHolder.reset(); } } public Set getModifyAdditions() { if (modifyHolder == null) { return null; } else { return modifyHolder.getModifyAdditions(); } } public Set getModifyRemovals() { if (modifyHolder == null) { return null; } else { return modifyHolder.getModifyRemovals(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy