package origo.helpers.forms; import org.apache.commons.lang.StringUtils; import origo.helpers.ReflectionHelper; import origo.helpers.SettingsHelper; import play.modules.origo.core.CachedAnnotation; import play.modules.origo.core.Listeners; import play.modules.origo.core.Node; import play.modules.origo.core.annotations.forms.ProvidesForm; import java.util.*; /** * Helper to trigger \@Provides origo.listeners. Should not be used directly except in core and admin, use NodeHelper * instead when creating a new module. * * @see origo.helpers.NodeHelper * @see play.modules.origo.core.annotations.Provides */ public class ProvidesFormHelper { public static <T> T triggerListener(String withType, Node node) { //noinspection unchecked return (T) triggerListener(withType, node, Collections.<Class, Object>emptyMap()); } public static <T> T triggerListener(String withType, Node node, Class argType, Object arg) { //noinspection unchecked return (T) triggerListener(withType, node, Collections.<Class, Object>singletonMap(argType, arg)); } public static <T> T triggerListener(String withType, Node node, Map<Class, Object> args) { CachedAnnotation cachedAnnotation = findListener(withType); Map<Class, Object> parameters = new HashMap<Class, Object>(); parameters.put(Node.class, node); parameters.putAll(args); //noinspection unchecked return (T) ReflectionHelper.invokeMethod(cachedAnnotation.method, parameters); } /** * Collects all \@Provides.with for the specified providesType. To be used when choosing a type for a new item for * instance or to find all DASHBOARD_ITEM's for the admin module. * * @return a list of all "with" added to the system. */ public static Set<String> getAllProvidesForm() { Set<String> providedTypes = new HashSet<String>(); List<CachedAnnotation> cachedAnnotations = Listeners.getListenersForAnnotationType(ProvidesForm.class); for (CachedAnnotation cachedAnnotation : cachedAnnotations) { providedTypes.add(((ProvidesForm) cachedAnnotation.annotation).with()); } return providedTypes; } private static CachedAnnotation findListener(String withType) { CachedAnnotation listener = findProvidersForType(withType); if (listener == null) { listener = findProvidersForType(SettingsHelper.Core.getDefaultFormProviderType()); if (listener == null) { throw new RuntimeException("Unable to find a form provider for type \'" + withType + "\' and the default form provider from settings is also not available"); } } return listener; } private static CachedAnnotation findProvidersForType(final String withType) { List<CachedAnnotation> providers = Listeners.getListenersForAnnotationType(ProvidesForm.class, new CachedAnnotation.ListenerSelector() { @Override public boolean isCorrectListener(CachedAnnotation listener) { ProvidesForm annotation = (ProvidesForm) listener.annotation; return (annotation.with().equals(withType) || StringUtils.isBlank(withType)); } }); if (!providers.isEmpty()) { if (providers.size() > 1) { throw new RuntimeException("Only one @Provides per type (attribute 'with') is allowed"); } return providers.iterator().next(); } else { return null; } } }