Skip to content

Commit e486b00

Browse files
committed
make NamespacedIdentifier an interface
1 parent 0696d1c commit e486b00

File tree

6 files changed

+136
-65
lines changed

6 files changed

+136
-65
lines changed
Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package net.ornithemc.osl.core.api.util;
22

3-
import java.util.Objects;
4-
53
/**
64
* Namespaced identifiers are two-part strings that uniquely point to content in Minecraft.
75
* The two parts are the namespace and the identifier. They can be combined into a single
@@ -18,69 +16,23 @@
1816
* <p>
1917
* Namespaces may only contain alphanumeric characters [a-zA-Z0-9] and special characters
2018
* [-._]. Identifiers may also contain the special character [/].
21-
* <p>
22-
* This class is essentially equivalent to Vanilla's {@code Identifier}. It was added for a
23-
* few reasons. For one, Vanilla's {@code Identifier} was only added in 13w21a, and then was
24-
* client-only until 14w27b. Implementation details of this class also changed a few times,
25-
* and only since 17w43a were {@code Identifiers} validated in any way.
26-
* <br> This class is available for all Minecraft versions, without any version-specific
27-
* implementation details.
2819
*/
29-
public final class NamespacedIdentifier {
20+
public interface NamespacedIdentifier {
3021

3122
/**
3223
* The separator between the namespace and identifier in the {@code String}
3324
* representation of a {@code NamespacedIdentifier}.
3425
*/
35-
public static final char SEPARATOR = ':';
36-
37-
/**
38-
* The namespace of this {@code NamespacedIdentifier}.
39-
*/
40-
private final String namespace;
41-
/**
42-
* The identifier of this {@code NamespacedIdentifier}.
43-
*/
44-
private final String identifier;
45-
46-
NamespacedIdentifier(String namespace, String identifier) {
47-
this.namespace = namespace;
48-
this.identifier = identifier;
49-
}
50-
51-
@Override
52-
public boolean equals(Object o) {
53-
if (this == o) {
54-
return true;
55-
}
56-
if (!(o instanceof NamespacedIdentifier)) {
57-
return false;
58-
}
59-
NamespacedIdentifier id = (NamespacedIdentifier) o;
60-
return namespace.equals(id.namespace) && identifier.equals(id.identifier);
61-
}
62-
63-
@Override
64-
public int hashCode() {
65-
return Objects.hash(namespace, identifier);
66-
}
67-
68-
@Override
69-
public String toString() {
70-
return namespace + SEPARATOR + identifier;
71-
}
26+
static char SEPARATOR = ':';
7227

7328
/**
7429
* @return the namespace of this {@code NamespacedIdentifier}.
7530
*/
76-
public String getNamespace() {
77-
return namespace;
78-
}
31+
String namespace();
7932

8033
/**
8134
* @return the identifier of this {@code NamespacedIdentifier}.
8235
*/
83-
public String getIdentifier() {
84-
return identifier;
85-
}
36+
String identifier();
37+
8638
}

libraries/core/src/main/java/net/ornithemc/osl/core/api/util/NamespacedIdentifiers.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import net.ornithemc.osl.core.impl.util.NamespacedIdentifierException;
44
import net.ornithemc.osl.core.impl.util.NamespacedIdentifierParseException;
5+
import net.ornithemc.osl.core.impl.util.NamespacedIdentifierImpl;
56

67
/**
78
* Utility methods for creating and validating {@link NamespacedIdentifier}s.
@@ -27,15 +28,6 @@ public final class NamespacedIdentifiers {
2728
*/
2829
public static final int MAX_LENGTH_IDENTIFIER = Integer.MAX_VALUE;
2930

30-
/**
31-
* Construct a {@code NamespacedIdentifier} without validating it.
32-
*
33-
* @deprecated use {@link #from(String, String)} instead
34-
*/
35-
public static NamespacedIdentifier of(String namespace, String identifier) {
36-
return new NamespacedIdentifier(namespace, identifier);
37-
}
38-
3931
/**
4032
* Construct and validate a {@code NamespacedIdentifier} with the default namespace and the given identifier.
4133
*
@@ -55,7 +47,7 @@ public static NamespacedIdentifier from(String identifier) {
5547
* if the given namespace or identifier is invalid.
5648
*/
5749
public static NamespacedIdentifier from(String namespace, String identifier) {
58-
return new NamespacedIdentifier(
50+
return new NamespacedIdentifierImpl(
5951
validateNamespace(namespace),
6052
validateIdentifier(identifier)
6153
);
@@ -91,8 +83,8 @@ public static NamespacedIdentifier parse(String s) {
9183
*/
9284
public static NamespacedIdentifier validate(NamespacedIdentifier id) {
9385
try {
94-
validateNamespace(id.getNamespace());
95-
validateIdentifier(id.getIdentifier());
86+
validateNamespace(id.namespace());
87+
validateIdentifier(id.identifier());
9688

9789
return id;
9890
} catch (NamespacedIdentifierException e) {
@@ -133,4 +125,8 @@ public static String validateIdentifier(String identifier) {
133125

134126
return identifier;
135127
}
128+
129+
public static boolean equals(NamespacedIdentifier a, NamespacedIdentifier b) {
130+
return a.namespace().equals(b.namespace()) && a.identifier().equals(b.identifier());
131+
}
136132
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package net.ornithemc.osl.core.impl.mixin;
2+
3+
import org.spongepowered.asm.mixin.Mixin;
4+
import org.spongepowered.asm.mixin.Pseudo;
5+
import org.spongepowered.asm.mixin.Shadow;
6+
import org.spongepowered.asm.mixin.injection.At;
7+
import org.spongepowered.asm.mixin.injection.Inject;
8+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
9+
10+
import net.minecraft.client.resource.Identifier;
11+
12+
import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
13+
import net.ornithemc.osl.core.api.util.NamespacedIdentifiers;
14+
15+
@Pseudo // needed because Identifier does not exist in all versions
16+
@Mixin(Identifier.class)
17+
public class IdentifierMixin implements NamespacedIdentifier { // TODO: interface injection
18+
19+
@Shadow
20+
private String namespace;
21+
@Shadow
22+
private String path;
23+
24+
@Inject(
25+
method = "equals",
26+
remap = false,
27+
cancellable = true,
28+
at = @At(
29+
value = "HEAD"
30+
)
31+
)
32+
private void osl$core$equalsNamespacedIdentifier(Object o, CallbackInfoReturnable<Boolean> cir) {
33+
if (o instanceof NamespacedIdentifier) {
34+
cir.setReturnValue(NamespacedIdentifiers.equals(this, (NamespacedIdentifier) o));
35+
}
36+
}
37+
38+
@Override
39+
public String namespace() {
40+
return namespace;
41+
}
42+
43+
@Override
44+
public String identifier() {
45+
return path;
46+
}
47+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package net.ornithemc.osl.core.impl.util;
2+
3+
import net.ornithemc.osl.core.api.util.NamespacedIdentifier;
4+
import net.ornithemc.osl.core.api.util.NamespacedIdentifiers;
5+
6+
/**
7+
* This class is a version-agnostic implementation of {@link NamespacedIdentifier}.
8+
* <p>
9+
* This class is essentially equivalent to Vanilla's {@code Identifier}. It was added for a
10+
* few reasons. For one, Vanilla's {@code Identifier} was only added in 13w21a, and then was
11+
* client-only until 14w27b. Implementation details of this class also changed a few times,
12+
* and only since 17w43a were {@code Identifiers} validated in any way.
13+
* <br> This class is available for all Minecraft versions, without any version-specific
14+
* implementation details.
15+
*/
16+
public final class NamespacedIdentifierImpl implements NamespacedIdentifier {
17+
18+
private final String namespace;
19+
private final String identifier;
20+
21+
public NamespacedIdentifierImpl(String namespace, String identifier) {
22+
this.namespace = namespace;
23+
this.identifier = identifier;
24+
}
25+
26+
@Override
27+
public boolean equals(Object o) {
28+
if (this == o) {
29+
return true;
30+
}
31+
if (!(o instanceof NamespacedIdentifier)) {
32+
return false;
33+
}
34+
return NamespacedIdentifiers.equals(this, (NamespacedIdentifier) o);
35+
}
36+
37+
@Override
38+
public int hashCode() {
39+
// this impl matches Vanilla Identifier's impl
40+
return 31 * namespace.hashCode() + identifier.hashCode();
41+
}
42+
43+
@Override
44+
public String toString() {
45+
return namespace + SEPARATOR + identifier;
46+
}
47+
48+
@Override
49+
public String namespace() {
50+
return namespace;
51+
}
52+
53+
@Override
54+
public String identifier() {
55+
return identifier;
56+
}
57+
}

libraries/core/src/main/resources/fabric.mod.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"license": "Apache-2.0",
1717
"icon": "assets/ornithe-standard-libraries/core/icon.png",
1818
"environment": "*",
19+
"mixins": [
20+
"osl.core.mixins.json"
21+
],
1922
"depends": {
2023
"fabricloader": ">=0.16.0"
2124
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"required": true,
3+
"minVersion": "0.8",
4+
"package": "net.ornithemc.osl.core.impl.mixin",
5+
"compatibilityLevel": "JAVA_8",
6+
"mixins": [
7+
"IdentifierMixin"
8+
],
9+
"client": [
10+
],
11+
"server": [
12+
],
13+
"injectors": {
14+
"defaultRequire": 1
15+
}
16+
}

0 commit comments

Comments
 (0)