package org.fenixedu.bennu.core.bootstrap; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.fenixedu.bennu.core.bootstrap.annotations.Bootstrap; import org.fenixedu.bennu.core.bootstrap.annotations.Field; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.Atomic.TxMode; import com.google.gson.JsonObject; public class SectionsBootstrapper { /** * Invokes all the declared methods with a {@link Bootstrap} annotation. * * @param json * the json that for each declared {@link Field} maps its key on its value. * * @throws Throwable * If errors ocurred during the bootstrap */ @Atomic(mode = TxMode.WRITE) public static void bootstrapAll(JsonObject json) throws Throwable { Class<?>[] sections = BootstrapperRegistry.getSections().toArray(new Class<?>[0]); Object superSection = SectionInvocationHandler.newInstance(json, sections); for (Method method : BootstrapperRegistry.getBootstrapMethods()) { Object[] args = new Object[method.getParameterTypes().length]; Arrays.fill(args, superSection); try { List<BootstrapError> errors = invokeIt(method, args); if (!errors.isEmpty()) { throw new BootstrapException(errors); } } catch (InvocationTargetException e) { throw e.getCause(); } } } private static List<BootstrapError> invokeIt(Method method, Object[] args) throws Exception { List<BootstrapError> errors = new ArrayList<>(); Object result = method.invoke(null, args); if (result != null) { if (Collection.class.isAssignableFrom(result.getClass())) { for (Object item : (Collection<?>) result) { if (BootstrapError.class.isAssignableFrom(item.getClass())) { errors.add((BootstrapError) item); } } } else if (BootstrapError.class.isAssignableFrom(result.getClass())) { errors.add((BootstrapError) result); } } return errors; } /* * This exception is thrown to indicate the Fenix Framework that it should abort the transaction. */ public static class BootstrapException extends Exception { private static final long serialVersionUID = -5494716182369251565L; private final List<BootstrapError> errors; public BootstrapException(List<BootstrapError> errors) { this.errors = errors; } public List<BootstrapError> getErrors() { return errors; } } }