ActionFactory { public static BaseSpellAction construct(String actionClassName) throws ActionFactoryException { List<String> attempts = new ArrayList<>(); for (ActionResolver resolver : resolvers) { ActionConstructor constructor = resolver.resolve(actionClassName, attempts); if (constructor != null) { return constructor.construct(); } } throw new ActionFactoryException( "Failed to resolve class: " + actionClassName + "\nTried: " + attempts); } private  ActionFactory(); static List<ActionResolver> getActionResolvers(); static void registerResolver(ActionResolver actionResolver); static void registerResolver(ActionResolver actionResolver,
            boolean highPriority); static void removeResolver(ActionResolver actionResolver); static void registerActionClass(String name, Class<?> clazz); static BaseSpellAction construct(String actionClassName);  }
@Test(expected = ActionFactoryException.class) public void testInvalidClass() throws ActionFactoryException { ActionFactory.construct("invalid-class%name"); }
@Test public void testInternalClass() throws ActionFactoryException { assertTrue(ActionFactory.construct( "Absorb") instanceof AbsorbAction); assertTrue(ActionFactory.construct( "AbsorbAction") instanceof AbsorbAction); assertTrue(ActionFactory.construct( "com.elmakers.mine.bukkit.action.builtin.Absorb") instanceof AbsorbAction); assertTrue(ActionFactory.construct( "com.elmakers.mine.bukkit.action.builtin.AbsorbAction") instanceof AbsorbAction); }