package rescuecore2.registry; import java.util.EnumSet; import java.io.InputStream; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import rescuecore2.messages.Message; /** An abstract message factory with helper methods for defining URNs with enums. @param <T> An enum type that defines the URNs this factory knows about. */ public abstract class AbstractMessageFactory<T extends Enum<T>> implements MessageFactory { private Class<T> clazz; private Method fromString; /** Constructor for AbstractMessageFactory. @param clazz The class of enum this factory uses. */ protected AbstractMessageFactory(Class<T> clazz) { this.clazz = clazz; try { fromString = clazz.getDeclaredMethod("fromString", String.class); } catch (NoSuchMethodException e) { fromString = null; } } @Override public String[] getKnownMessageURNs() { EnumSet<T> set = getKnownMessageURNsEnum(); String[] result = new String[set.size()]; int i = 0; for (T next : set) { result[i++] = next.toString(); } return result; } @Override @SuppressWarnings("unchecked") public Message makeMessage(String urn, InputStream data) throws IOException { T t = null; if (fromString != null) { try { t = (T)fromString.invoke(null, urn); } catch (IllegalAccessException e) { t = null; } catch (InvocationTargetException e) { t = null; } } if (t == null) { t = Enum.valueOf(clazz, urn); } return makeMessage(t, data); } /** Get an EnumSet containing known message URNs. Default implementation returns EnumSet.allOf(T). @return An EnumSet containing known message URNs. */ protected EnumSet<T> getKnownMessageURNsEnum() { return EnumSet.allOf(clazz); } /** Create a message based on its urn and populate it with data from a stream. If the urn is not recognised then return null. @param urn The urn of the message type to create. @param data An InputStream to read message data from. @return A new Message object, or null if the urn is not recognised. @throws IOException If there is a problem reading the stream. */ protected abstract Message makeMessage(T urn, InputStream data) throws IOException; }