Last active
March 12, 2019 06:30
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum Color { | |
RED, GREEN, BLUE,; | |
static { | |
Mirror.of(RGB.class); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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])); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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