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