001package io.ebeanservice.docstore.api.support;
002
003import io.ebean.FetchPath;
004import io.ebean.text.PathProperties;
005import io.ebeaninternal.server.deploy.BeanDescriptor;
006import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
007
008import java.util.HashMap;
009import java.util.Map;
010import java.util.Set;
011
012/**
013 * Document structure for mapping to document store.
014 */
015public class DocStructure {
016
017  /**
018   * The full document structure.
019   */
020  private final PathProperties doc;
021
022  /**
023   * The embedded document structures by path.
024   */
025  private final Map<String, PathProperties> embedded = new HashMap<>();
026
027  private final Map<String, PathProperties> manyRoot = new HashMap<>();
028
029  /**
030   * Create given an initial deployment doc mapping.
031   */
032  public DocStructure(PathProperties pathProps) {
033    this.doc = pathProps;
034  }
035
036  /**
037   * Add a property at the root level.
038   */
039  public void addProperty(String name) {
040    doc.addToPath(null, name);
041  }
042
043  /**
044   * Add an embedded property with it's document structure.
045   */
046  public void addNested(String path, PathProperties embeddedDoc) {
047    doc.addNested(path, embeddedDoc);
048    embedded.put(path, embeddedDoc);
049  }
050
051  /**
052   * Return the document structure.
053   */
054  public PathProperties doc() {
055    return doc;
056  }
057
058  /**
059   * Return the document structure for an embedded path.
060   */
061  public FetchPath getEmbedded(String path) {
062    return embedded.get(path);
063  }
064
065  public FetchPath getEmbeddedManyRoot(String path) {
066    return manyRoot.get(path);
067  }
068
069  /**
070   * For 'many' nested properties we need an additional root based graph to fetch and update.
071   */
072  public <T> void prepareMany(BeanDescriptor<T> desc) {
073    Set<String> strings = embedded.keySet();
074    for (String prop : strings) {
075      BeanPropertyAssoc<?> embProp = (BeanPropertyAssoc<?>) desc.findProperty(prop);
076      if (embProp.isMany()) {
077        prepare(prop, embProp);
078      }
079    }
080  }
081
082  /**
083   * Add a PathProperties for an embedded 'many' property (at the root level).
084   */
085  private void prepare(String prop, BeanPropertyAssoc<?> embProp) {
086
087    BeanDescriptor<?> targetDesc = embProp.getTargetDescriptor();
088
089    PathProperties manyRootPath = new PathProperties();
090    manyRootPath.addToPath(null, targetDesc.getIdProperty().getName());
091    manyRootPath.addNested(prop, embedded.get(prop));
092
093    manyRoot.put(prop, manyRootPath);
094  }
095}