Package com.avaje.ebeaninternal.server.loadcontext

Source Code of com.avaje.ebeaninternal.server.loadcontext.DLoadContext

package com.avaje.ebeaninternal.server.loadcontext;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.bean.ObjectGraphOrigin;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebeaninternal.api.LoadContext;
import com.avaje.ebeaninternal.api.LoadSecondaryQuery;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryProperties;

/**
* Default implementation of LoadContext.
*/
public class DLoadContext implements LoadContext {

  private final SpiEbeanServer ebeanServer;
 
  private final BeanDescriptor<?> rootDescriptor;
 
  private final Map<String, DLoadBeanContext> beanMap = new HashMap<String, DLoadBeanContext>();
  private final Map<String, DLoadManyContext> manyMap = new HashMap<String, DLoadManyContext>();
 
  private final DLoadBeanContext rootBeanContext;
 
  private final Boolean readOnly;
  private final boolean excludeBeanCache; 
  private final int defaultBatchSize;
 
  /**
   * The path relative to the root of the object graph.
   */
  private final String relativePath; 
  private final ObjectGraphOrigin origin;
  private final boolean useAutofetchManager;
 
  private final Map<String,ObjectGraphNode> nodePathMap = new HashMap<String, ObjectGraphNode>();
   
  private PersistenceContext persistenceContext;
 
  private List<OrmQueryProperties> secQuery;

  public DLoadContext(OrmQueryRequest<?> request) {

    this.persistenceContext = request.getPersistenceContext();
    this.ebeanServer = request.getServer();
    this.defaultBatchSize = ebeanServer.getLazyLoadBatchSize();
    this.rootDescriptor = request.getBeanDescriptor();
   
    SpiQuery<?> query = request.getQuery();
    this.readOnly = query.isReadOnly();   
    this.excludeBeanCache = Boolean.FALSE.equals(query.isUseBeanCache());
    this.useAutofetchManager = query.getAutoFetchManager() != null;   
       
    ObjectGraphNode parentNode = query.getParentNode();
    if (parentNode != null){
      this.origin = parentNode.getOriginQueryPoint();
      this.relativePath = parentNode.getPath();
    } else {
      this.origin = null;
      this.relativePath = null;
    }
   
    // initialise rootBeanContext after origin and relativePath have been set
    this.rootBeanContext = new DLoadBeanContext(this, rootDescriptor, null, defaultBatchSize, null);
  }

  protected boolean isExcludeBeanCache() {
    return excludeBeanCache;
  }

  /**
   * Return the minimum batch size when using QueryIterator with query joins.
   */
  public int getSecondaryQueriesMinBatchSize(OrmQueryRequest<?> parentRequest, int defaultQueryBatch) {

    if (secQuery == null) {
      return -1;
    }

    int maxBatch = 0;
    for (int i = 0; i < secQuery.size(); i++) {
      int batchSize = secQuery.get(i).getQueryFetchBatch();
      if (batchSize == 0) {
        batchSize = defaultQueryBatch;
      }
      maxBatch = Math.max(maxBatch, batchSize);
    }
    return maxBatch;
  }
   
  /**
   * Execute all the secondary queries.
   */
  public void executeSecondaryQueries(OrmQueryRequest<?> parentRequest, int defaultQueryBatch) {
   
    if (secQuery != null){
      for (int i = 0; i < secQuery.size(); i++) {
        OrmQueryProperties properties = secQuery.get(i);
       
        int batchSize = properties.getQueryFetchBatch();
        if (batchSize == 0){
          batchSize = defaultQueryBatch;
        }
        LoadSecondaryQuery load = getLoadSecondaryQuery(properties.getPath());
        load.loadSecondaryQuery(parentRequest, batchSize, properties.isQueryFetchAll());
      }
    }
  }
 
  /**
   * Return the LoadBeanContext or LoadManyContext for the given path.
   */
  private LoadSecondaryQuery getLoadSecondaryQuery(String path){
    LoadSecondaryQuery beanLoad = beanMap.get(path);
    if (beanLoad == null){
      beanLoad = manyMap.get(path);
    }
    return beanLoad;
  }

  /**
   * Remove the +query and +lazy secondary queries and
   * register them with their appropriate LoadBeanContext
   * or LoadManyContext.
   * <p>
   * The parts of the secondary queries are removed and used
   * by LoadBeanContext/LoadManyContext to build the appropriate
   * queries.
   * </p>
   */
  public void registerSecondaryQueries(SpiQuery<?> query) {
 
    secQuery = query.removeQueryJoins();
    if (secQuery != null){
      for (int i = 0; i < secQuery.size(); i++) {
        OrmQueryProperties props = secQuery.get(i);
        registerSecondaryQuery(props);
      }
    }
   
    List<OrmQueryProperties> lazyQueries = query.removeLazyJoins();
    if (lazyQueries != null){
      for (int i = 0; i < lazyQueries.size(); i++) {
        OrmQueryProperties lazyProps = lazyQueries.get(i);
        registerSecondaryQuery(lazyProps);
      }
    }
  }
 
  /**
   * Setup the load context at this path with OrmQueryProperties which is
   * used to build the appropriate query for +query or +lazy loading.
   */
  private void registerSecondaryQuery(OrmQueryProperties props) {
         
    String propName = props.getPath();
    ElPropertyValue elGetValue = rootDescriptor.getElGetValue(propName);

    boolean many = elGetValue.getBeanProperty().containsMany();
    registerSecondaryNode(many, props);
  }


  public ObjectGraphNode getObjectGraphNode(String path) {
 
    ObjectGraphNode node = nodePathMap.get(path);
    if (node == null){
      node = createObjectGraphNode(path);
      nodePathMap.put(path, node);
    }
   
    return node;
  }
 
  private ObjectGraphNode createObjectGraphNode(String path) {
   
    if (relativePath != null){
      if (path == null){
        path = relativePath;
      } else {
        path = relativePath+"."+path;
      }
    }
    return new ObjectGraphNode(origin, path);   
  }

  public boolean isUseAutofetchManager() {
    return useAutofetchManager;
  }
 
  public String getRelativePath() {
    return relativePath;
  }
 
  protected String getFullPath(String path) {
    if (relativePath == null) {
      return path;
    } else {
      return relativePath + "." + path;
    }
  }

  protected SpiEbeanServer getEbeanServer() {
    return ebeanServer;
  }
 
  /**
   * Return the parent state which defines the sharedInstance and readOnly status
   * which needs to be propagated to other beans and collections.
   */
  protected Boolean isReadOnly() {
    return readOnly;
  }
 
  public PersistenceContext getPersistenceContext() {
    return persistenceContext;
  }

  public void setPersistenceContext(PersistenceContext persistenceContext) {
    this.persistenceContext = persistenceContext;
  }

  public void register(String path, EntityBeanIntercept ebi){
    getBeanContext(path).register(ebi);
  }

  public void register(String path, BeanCollection<?> bc){
    getManyContext(path).register(bc);
  }
 
  private DLoadBeanContext getBeanContext(String path) {
    if (path == null){
      return rootBeanContext;
    }
    DLoadBeanContext beanContext = beanMap.get(path);
    if (beanContext == null){
      beanContext = createBeanContext(path, defaultBatchSize, null);
      beanMap.put(path, beanContext);
    }
    return beanContext;
  }
 
  private void registerSecondaryNode(boolean many, OrmQueryProperties props) {
   
    String path = props.getPath();
    int lazyJoinBatch = props.getLazyFetchBatch();
    int batchSize = lazyJoinBatch > 0 ? lazyJoinBatch : defaultBatchSize;
   
    if (many){
      DLoadManyContext manyContext = createManyContext(path, batchSize, props);
      manyMap.put(path, manyContext);
    } else {
      DLoadBeanContext beanContext = createBeanContext(path, batchSize, props);
      beanMap.put(path, beanContext);
    }
  }

  private DLoadManyContext getManyContext(String path) {
    if (path == null){
      throw new RuntimeException("path is null?");
    }
    DLoadManyContext ctx = manyMap.get(path);
    if (ctx == null){
      ctx = createManyContext(path, defaultBatchSize, null);
      manyMap.put(path, ctx);
    }
    return ctx;
  }
 
  private DLoadManyContext createManyContext(String path, int batchSize, OrmQueryProperties queryProps) {

    BeanPropertyAssocMany<?> p = (BeanPropertyAssocMany<?>)getBeanProperty(rootDescriptor, path);

    return new DLoadManyContext(this, p, path, batchSize, queryProps);
  }

  private DLoadBeanContext createBeanContext(String path, int batchSize, OrmQueryProperties queryProps) {

    BeanPropertyAssoc<?> p = (BeanPropertyAssoc<?>)getBeanProperty(rootDescriptor, path);
    BeanDescriptor<?> targetDescriptor = p.getTargetDescriptor();

    return new DLoadBeanContext(this, targetDescriptor, path, batchSize, queryProps);     
  }
 
  private BeanProperty getBeanProperty(BeanDescriptor<?> desc, String path){
    return desc.getBeanPropertyFromPath(path);
  }
 
}
TOP

Related Classes of com.avaje.ebeaninternal.server.loadcontext.DLoadContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.