001package io.ebean.bean;
002
003import java.io.Serializable;
004import java.util.Objects;
005
006/**
007 * Identifies a unique node of an object graph.
008 * <p>
009 * It represents a location relative to the root of an object graph and specific
010 * to a query and call stack hash.
011 * </p>
012 */
013public final class ObjectGraphNode implements Serializable {
014
015  private static final long serialVersionUID = 2087081778650228996L;
016
017  /**
018   * Identifies the origin.
019   */
020  private final ObjectGraphOrigin originQueryPoint;
021
022  /**
023   * The path relative to the root.
024   */
025  private final String path;
026
027  /**
028   * Create at a sub level.
029   */
030  public ObjectGraphNode(ObjectGraphNode parent, String path) {
031    this.originQueryPoint = parent.getOriginQueryPoint();
032    this.path = parent.getChildPath(path);
033  }
034
035  /**
036   * Create an the root level.
037   */
038  public ObjectGraphNode(ObjectGraphOrigin originQueryPoint, String path) {
039    this.originQueryPoint = originQueryPoint;
040    this.path = path;
041  }
042
043  /**
044   * Return the origin query point.
045   */
046  public ObjectGraphOrigin getOriginQueryPoint() {
047    return originQueryPoint;
048  }
049
050  private String getChildPath(String childPath) {
051    if (path == null) {
052      return childPath;
053    } else if (childPath == null) {
054      return path;
055    } else {
056      return path + "." + childPath;
057    }
058  }
059
060  /**
061   * Return the path relative to the root.
062   */
063  public String getPath() {
064    return path;
065  }
066
067  @Override
068  public String toString() {
069    return "origin:" + originQueryPoint + " path[" + path + "]";
070  }
071
072  @Override
073  public int hashCode() {
074    int hc = 92821 * originQueryPoint.hashCode();
075    hc = 92821 * hc + (path == null ? 0 : path.hashCode());
076    return hc;
077  }
078
079  @Override
080  public boolean equals(Object obj) {
081    if (obj == this) {
082      return true;
083    }
084    if (!(obj instanceof ObjectGraphNode)) {
085      return false;
086    }
087
088    ObjectGraphNode e = (ObjectGraphNode) obj;
089    return (Objects.equals(e.path, path))
090      && e.originQueryPoint.equals(originQueryPoint);
091  }
092}