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

io.ebeaninternal.server.expression.PrepareDocNested Maven / Gradle / Ivy

package io.ebeaninternal.server.expression;

import io.ebean.Junction;
import io.ebeaninternal.api.SpiExpression;
import io.ebeaninternal.server.deploy.BeanDescriptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Prepare nested path expressions for
 */
final class PrepareDocNested {

  /**
   * Prepare the top level expressions for nested path handling.
   */
  static void prepare(DefaultExpressionList expressions, BeanDescriptor beanDescriptor) {
    new PrepareDocNested(expressions, beanDescriptor, null).process();
  }

  /**
   * Prepare the Junction expressions for nested path handling.
   */
  static void prepare(DefaultExpressionList expressions, BeanDescriptor beanDescriptor, Junction.Type type) {
    new PrepareDocNested(expressions, beanDescriptor, type).process();
  }

  enum Mode {
    NONE,
    SINGLE,
    MIXED
  }

  private final Junction.Type type;
  private final DefaultExpressionList original;
  private final BeanDescriptor beanDescriptor;
  private final List origUnderlying;
  private final int origSize;

  private boolean hasNesting;
  private boolean hasMixedNesting;
  private String firstNestedPath;


  PrepareDocNested(DefaultExpressionList original, BeanDescriptor beanDescriptor, Junction.Type type) {
    this.type = type;
    this.beanDescriptor = beanDescriptor;
    this.original = original;
    this.origUnderlying = original.underlyingList();
    this.origSize = origUnderlying.size();
  }

  void process() {

    PrepareDocNested.Mode mode = determineMode();
    if (mode == PrepareDocNested.Mode.SINGLE) {
      original.setAllDocNested(firstNestedPath);

    } else if (mode == PrepareDocNested.Mode.MIXED) {
      original.setUnderlying(group());
    }

  }

  /**
   * Reorganise the flat list of expressions into a tree grouping expressions by nested path.
   * 

* Returns the new top level list of expressions. */ private List group() { Map groups = new LinkedHashMap<>(); // organise expressions by nestedPath for (int i = 0; i < origSize; i++) { SpiExpression expr = origUnderlying.get(i); String nestedPath = expr.nestedPath(beanDescriptor); Group group = groups.computeIfAbsent(nestedPath, Group::new); group.list.add(expr); } List newList = new ArrayList<>(); Collection values = groups.values(); for (Group group : values) { group.addTo(newList); } return newList; } /** * Determined the nested path mode. */ private Mode determineMode() { if (!hasNesting()) { // no nested paths at all return Mode.NONE; } if (!hasMixedNesting) { // single nested path for all expressions return Mode.SINGLE; } // mixed nested paths to underlying expression list needs re-organising by nested path return Mode.MIXED; } /** * Return true if the expressions have nested paths. */ private boolean hasNesting() { for (int i = 0; i < origSize; i++) { SpiExpression expr = origUnderlying.get(i); String nestedPath = expr.nestedPath(beanDescriptor); if (nestedPath == null) { hasMixedNesting = true; } if (nestedPath != null) { hasNesting = true; if (firstNestedPath == null) { firstNestedPath = nestedPath; } else if (hasMixedNesting || !firstNestedPath.equals(nestedPath)) { hasMixedNesting = true; return true; } } } return hasNesting; } /** * List of SpiExpression grouped by nested path. */ class Group { final String nestedPath; final List list = new ArrayList<>(); Group(String nestedPath) { this.nestedPath = nestedPath; } void addTo(List newList) { if (nestedPath == null) { newList.addAll(list); } else { newList.add(original.wrap(list, nestedPath, type)); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy