
com.almworks.jira.structure.api2g.item.ItemIdentity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of structure-api Show documentation
Show all versions of structure-api Show documentation
Public API for the Structure Plugin for JIRA
package com.almworks.jira.structure.api2g.item;
import com.almworks.jira.structure.api2g.Limits;
import com.atlassian.annotations.PublicApi;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.Immutable;
import java.io.Serializable;
import java.text.ParseException;
@PublicApi
@Immutable
// todo make sure all type ID Strings are intern()ed
public abstract class ItemIdentity implements Serializable {
// todo do we really need it?
public static final ItemIdentity ITEM_ZERO = longId("0", 0);
@NotNull
private final String myItemType;
private ItemIdentity(@NotNull String itemType) {
if (StringUtils.isBlank(itemType)) {
throw new IllegalArgumentException("item type must not be empty");
}
if (itemType.length() > Limits.MAX_MODULE_KEY_LENGTH) {
throw new IllegalArgumentException("item type must not be longer than " + Limits.MAX_MODULE_KEY_LENGTH + " chars");
}
myItemType = itemType;
}
@NotNull
public String getItemType() {
return myItemType;
}
public boolean isStringId() {
return false;
}
@NotNull
public String getStringId() {
throw new UnsupportedOperationException("Not a string ID");
}
public boolean isLongId() {
return false;
}
public long getLongId() {
throw new UnsupportedOperationException("Not a long ID");
}
@NotNull
public static ItemIdentity stringId(@NotNull String itemType, @NotNull String stringId) {
return new StringIdentity(itemType, stringId);
}
@NotNull
public static ItemIdentity longId(@NotNull String itemType, long longId) {
return new LongIdentity(itemType, longId);
}
/**
* Creates either longId or stringId depending on the value of stringId.
*/
public static ItemIdentity id(@NotNull String itemType, long longId, @Nullable String stringId) {
if (StringUtils.isBlank(stringId)) {
return longId(itemType, longId);
} else if (longId == 0) {
return stringId(itemType, stringId);
} else {
throw new IllegalArgumentException("item identity cannot have both string (" + stringId + ") and long (" + longId + ") components");
}
}
// todo maybe move to tests if there's no need for canonical representation of item id
// Must be compatible with ItemSerializer and Deserializer.js
@NotNull
public static ItemIdentity parse(String id) throws ParseException {
if (id == null || id.isEmpty()) {
throw new ParseException("cannot parse empty id", 0);
}
int k = id.indexOf('/');
if (k < 0) {
try {
long longId = Long.parseLong(id);
return CoreIdentities.issue(longId);
} catch (NumberFormatException e) {
throw new ParseException("unknown id format [" + id + "]", id.length());
}
}
if (k == 0) {
throw new ParseException("empty type id [" + id + "]", 0);
}
if (k == id.length() - 1) {
throw new ParseException("unexpected end of line [" + id + "]", id.length());
}
String typeId = id.substring(0, k);
if (id.charAt(k + 1) == '/') {
String sid = id.substring(k + 2);
if (sid.isEmpty()) {
throw new ParseException("empty sid [" + id + "]", k + 2);
}
try {
return stringId(typeId, sid);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage(), k + 1);
}
} else {
String lid = id.substring(k + 1);
if (lid.isEmpty()) {
throw new ParseException("empty id [" + id + "]", k + 1);
}
try {
return longId(typeId, Long.parseLong(lid));
} catch (NumberFormatException e) {
throw new ParseException("bad id format [" + id + "]", k + 1);
} catch (IllegalArgumentException e) {
throw new ParseException(e.getMessage(), k + 1);
}
}
}
@PublicApi
public static final class StringIdentity extends ItemIdentity implements Serializable {
@NotNull
private final String myStringId;
private StringIdentity(@NotNull String itemType, @NotNull String stringId) {
super(itemType);
if (StringUtils.isBlank(stringId)) {
throw new IllegalArgumentException("string id must not be empty");
}
if (stringId.length() > Limits.MAX_ITEM_STRING_ID_LENGTH) {
throw new IllegalArgumentException("string id must not be longer than " + Limits.MAX_ITEM_STRING_ID_LENGTH + " chars");
}
myStringId = stringId;
}
@Override
public boolean isStringId() {
return true;
}
@Override
@NotNull
public String getStringId() {
return myStringId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
StringIdentity that = (StringIdentity) o;
return myStringId.equals(that.myStringId) && getItemType().equals(that.getItemType());
}
@Override
public int hashCode() {
return myStringId.hashCode() * 31 + getItemType().hashCode();
}
@Override
public String toString() {
return getItemType() + "//" + myStringId;
}
}
@PublicApi
public static final class LongIdentity extends ItemIdentity implements Serializable {
private final long myLongId;
private LongIdentity(@NotNull String itemType, long longId) {
super(itemType);
myLongId = longId;
}
@Override
public boolean isLongId() {
return true;
}
@Override
public long getLongId() {
return myLongId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LongIdentity that = (LongIdentity) o;
return myLongId == that.myLongId && getItemType().equals(that.getItemType());
}
@Override
public int hashCode() {
return (int) (myLongId ^ (myLongId >>> 32)) * 31 + getItemType().hashCode();
}
@Override
public String toString() {
return getItemType() + "/" + myLongId;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy