Minestom/src/main/java/net/minestom/server/utils/NamespaceID.java

153 lines
4.5 KiB
Java
Raw Normal View History

2020-05-18 21:11:59 +02:00
package net.minestom.server.utils;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.kyori.adventure.key.Key;
2020-10-18 18:27:57 +02:00
import org.jetbrains.annotations.NotNull;
2020-05-18 21:11:59 +02:00
import java.util.Objects;
/**
* Represents a namespaced ID
* https://minecraft.gamepedia.com/Namespaced_ID
*/
public class NamespaceID implements CharSequence, Key {
2020-05-18 21:11:59 +02:00
private static final Int2ObjectOpenHashMap<NamespaceID> cache = new Int2ObjectOpenHashMap<>();
2020-10-18 18:27:57 +02:00
private static final String legalLetters = "[0123456789abcdefghijklmnopqrstuvwxyz_-]+";
2020-10-25 00:00:32 +02:00
private static final String legalPathLetters = "[0123456789abcdefghijklmnopqrstuvwxyz./_-]+";
2020-05-18 21:11:59 +02:00
private final String domain;
private final String path;
private final String full;
/**
* Extracts the domain from the namespace ID. "minecraft:stone" would return "minecraft".
* If no ':' character is found, "minecraft" is returned.
*
2020-11-10 08:01:27 +01:00
* @param namespaceID the namespace id to get the domain from
2020-05-18 21:11:59 +02:00
* @return the domain of the namespace ID
*/
2020-11-10 08:01:27 +01:00
@NotNull
public static String getDomain(@NotNull String namespaceID) {
final int index = namespaceID.indexOf(':');
if (index < 0)
2020-05-18 21:11:59 +02:00
return "minecraft";
2020-10-22 12:55:53 +02:00
assert namespaceID.indexOf(':', index + 1) == -1 : "Namespace ID can only have at most one colon ':' (" + namespaceID + ")";
2020-05-18 21:11:59 +02:00
return namespaceID.substring(0, index);
}
/**
* Extracts the path from the namespace ID. "minecraft:blocks/stone" would return "blocks/stone".
* If no ':' character is found, the <pre>namespaceID</pre> is returned.
*
2020-11-10 08:01:27 +01:00
* @param namespaceID the namespace id to get the path from
2020-05-18 21:11:59 +02:00
* @return the path of the namespace ID
*/
2020-11-10 08:01:27 +01:00
public static String getPath(@NotNull String namespaceID) {
final int index = namespaceID.indexOf(':');
if (index < 0)
2020-05-18 21:11:59 +02:00
return namespaceID;
2020-10-22 12:55:53 +02:00
assert namespaceID.indexOf(':', index + 1) == -1 : "Namespace ID can only have at most one colon ':' (" + namespaceID + ")";
return namespaceID.substring(index + 1);
2020-05-18 21:11:59 +02:00
}
static int hash(String domain, String path) {
return Objects.hash(domain, path);
}
public static NamespaceID from(String domain, String path) {
final int hash = hash(domain, path);
2020-05-18 21:11:59 +02:00
return cache.computeIfAbsent(hash, _unused -> new NamespaceID(domain, path));
}
public static NamespaceID from(String id) {
return from(getDomain(id), getPath(id));
}
public static NamespaceID from(Key key) {
return from(key.asString());
}
2020-11-10 08:01:27 +01:00
private NamespaceID(@NotNull String path) {
final int index = path.indexOf(':');
if (index < 0) {
2020-05-18 21:11:59 +02:00
this.domain = "minecraft";
this.path = path;
} else {
this.domain = path.substring(0, index);
this.path = path.substring(index + 1);
2020-05-18 21:11:59 +02:00
}
this.full = toString();
2020-10-18 18:27:57 +02:00
validate();
2020-05-18 21:11:59 +02:00
}
private NamespaceID(String domain, String path) {
this.domain = domain;
this.path = path;
this.full = toString();
2020-10-18 18:27:57 +02:00
validate();
}
private void validate() {
2020-10-22 12:55:53 +02:00
assert !domain.contains(".") && !domain.contains("/") : "Domain cannot contain a dot nor a slash character (" + full + ")";
assert domain.matches(legalLetters) : "Illegal character in domain (" + full + "). Must match " + legalLetters;
2020-10-25 00:00:32 +02:00
assert path.matches(legalPathLetters) : "Illegal character in path (" + full + "). Must match " + legalPathLetters;
2020-05-18 21:11:59 +02:00
}
public String getDomain() {
return domain;
}
public String getPath() {
return path;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(!(o instanceof Key)) return false;
final Key that = (Key) o;
return Objects.equals(this.domain, that.namespace()) && Objects.equals(this.path, that.value());
2020-05-18 21:11:59 +02:00
}
@Override
public int hashCode() {
return hash(domain, path);
}
@Override
public int length() {
return full.length();
}
@Override
public char charAt(int index) {
return full.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return full.subSequence(start, end);
}
2020-10-18 18:27:57 +02:00
@NotNull
2020-05-18 21:11:59 +02:00
@Override
public String toString() {
return domain + ":" + path;
2020-05-18 21:11:59 +02:00
}
2021-03-22 22:26:14 +01:00
@Override
public @NotNull String namespace() {
return this.domain;
}
@Override
public @NotNull String value() {
return this.path;
}
@Override
public @NotNull String asString() {
return this.full;
2021-03-22 22:26:14 +01:00
}
2020-05-18 21:11:59 +02:00
}