Skip to content

Instantly share code, notes, and snippets.

@alexradzin
Last active March 12, 2019 06:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexradzin/8f17d11a2907ee6d5a7d81223f9e2e77 to your computer and use it in GitHub Desktop.
Save alexradzin/8f17d11a2907ee6d5a7d81223f9e2e77 to your computer and use it in GitHub Desktop.
Simple utility that helps to create mirror enums safe for modification of the source enum.
public enum Color {
RED, GREEN, BLUE,;
static {
Mirror.of(RGB.class);
}
}
package org.enumus;
import static java.lang.String.format;
import static java.util.Arrays.stream;
public class Mirror {
@SuppressWarnings("unchecked")
public static <E extends Enum<E>> void of(Class<E> e) {
Class<? extends Enum> caller = discoverCaller();
Mirror.mirrors(caller, e);
}
@SuppressWarnings("unchecked")
private static <E extends Enum<E>> Class<E> discoverCaller() {
try {
return (Class<E>)Class.forName(stream(new Throwable().getStackTrace()).filter(e -> !e.getClassName()
.equals(Mirror.class.getName()))
.findFirst()
.orElseThrow(() -> new IllegalStateException(format("Cannot discover caller's class. It seems that %s calls itself", Mirror.class)))
.getClassName());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}
public static <T extends Enum<T>, M extends Enum<M>> void mirrors(Class<T> s, Class<M> m) {
T[] source = s.getEnumConstants();
M[] mirror = m.getEnumConstants();
if (source.length != mirror.length) {
throw new IllegalStateException(format("Source and mirror enums have different number of elements: %s#%d vs. %s#%d", s.getName(), source.length, m.getName(), mirror.length));
}
for (int i = 0; i < source.length; i++) {
if (!source[i].name().equals(mirror[i].name())) {
throw new IllegalStateException(format("Element #%d of mirror %s.%s does not reflect the source %s.%s", i, m.getName(), mirror[i], s.getName(), source[i]));
}
}
}
}
/**
* Simple example that demonstrates mirror functionality.
* It is enough to mention the miror enum in code; its static initializer runs and invokes {@code Mirror} validator.
* If enums are different exception is thrown.
*/
public class MyMain {
public static void main(String[] args) {
System.out.println(Color.RED);
}
}
public enum RGB {
RED, GREEN, BLUE,;
static {
Mirror.of(Color.class);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment