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