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

com.almworks.jira.structure.api.row.SimpleRow Maven / Gradle / Ivy

The newest version!
package com.almworks.jira.structure.api.row;

import com.almworks.jira.structure.api.item.ItemIdentity;
import com.almworks.jira.structure.api.item.ItemResolver;
import com.atlassian.annotations.Internal;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@Internal
public class SimpleRow implements StructureRow {
  protected final long myRowId;

  @NotNull
  protected final ItemIdentity myItemId;

  protected final long mySemantics;

  @NotNull
  protected final ItemResolver myResolver;

  @Nullable
  private Object myItem;
  private volatile boolean myItemLoaded;

  @NotNull
  public static StructureRow create(long rowId, @NotNull ItemIdentity itemId, long semantics, @Nullable ItemResolver resolver) {
    return create(rowId, itemId, semantics, resolver, false);
  }

  public static StructureRow create(long rowId, ItemIdentity itemId, long semantics, @Nullable ItemResolver resolver, ItemAccessMode accessMode) {
    if (accessMode == ItemAccessMode.ITEM_NOT_NEEDED) {
      return new ShallowRow(rowId, itemId, semantics);
    }
    return create(rowId, itemId, semantics, resolver, accessMode == ItemAccessMode.SKIP_ACCESS_CHECK);
  }

  public static StructureRow create(long rowId, ItemIdentity itemId, long semantics, @Nullable ItemResolver resolver, boolean skipAccessCheck) {
    if (resolver == null) {
      return new ShallowRow(rowId, itemId, semantics);
    }
    if (skipAccessCheck) {
      return new Unchecked(rowId, itemId, semantics, resolver);
    } else {
      return new SimpleRow(rowId, itemId, semantics, resolver);
    }
  }

  private SimpleRow(long rowId, @NotNull ItemIdentity itemId, long semantics, @NotNull ItemResolver resolver) {
    StructureRows.validateForestRowId(rowId);
    myRowId = rowId;
    myItemId = itemId;
    mySemantics = semantics;
    myResolver = resolver;
  }

  @Override
  public long getRowId() {
    return myRowId;
  }

  @NotNull
  @Override
  public ItemIdentity getItemId() {
    return myItemId;
  }

  @Override
  public long getSemantics() {
    return mySemantics;
  }

  protected String getQualifier() {
    return "SimpleRow";
  }

  @Override
  public String toString() {
    return getQualifier() + "[" +  myRowId + ":" + myItemId + ":" + mySemantics + "]";
  }

  @Nullable
  @Override
  public  I getItem(@NotNull Class itemClass) {
    if (!myItemLoaded) {
      synchronized (this) {
        if (!myItemLoaded) {
          try {
            myItem = resolve();
          } finally {
            myItemLoaded = true;
          }
        }
      }
    }
    return itemClass.isInstance(myItem) ? itemClass.cast(myItem) : null;
  }

  protected Object resolve() {
    return myResolver.resolveItem(myItemId, Object.class);
  }

  public static StructureRow tryMakeUnchecked(StructureRow r) {
    if (r instanceof Unchecked || !(r instanceof SimpleRow)) return r;
    ItemResolver resolver = ((SimpleRow) r).myResolver;
    return new Unchecked(r.getRowId(), r.getItemId(), r.getSemantics(), resolver);
  }


  static final class Unchecked extends SimpleRow {
    private Unchecked(long rowId, @NotNull ItemIdentity itemId, long semantics, @NotNull ItemResolver resolver) {
      super(rowId, itemId, semantics, resolver);
    }

    @Override
    protected Object resolve() {
      return myResolver.resolveUnchecked(myItemId);
    }

    @Override
    protected String getQualifier() {
      return "SimpleRow(unchecked)";
    }
  }
}