package greencode.kernel; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.SQLException; import greencode.database.annotation.Connection; import greencode.database.implementation.DatabaseConnectionEvent; import greencode.http.Conversation; import greencode.http.HttpAction; import greencode.jscript.dom.Window; import greencode.jscript.dom.WindowHandle; import greencode.jscript.dom.window.annotation.ConversationAttribute; import greencode.jscript.dom.window.annotation.In; import greencode.jscript.dom.window.annotation.RequestParameter; import greencode.jscript.dom.window.annotation.SessionAttribute; import greencode.jscript.dom.window.annotation.UserPrincipal; import greencode.jscript.dom.window.annotation.Validate; import greencode.jscript.dom.window.annotation.ViewSessionAttribute; import greencode.util.ClassUtils; import greencode.util.GenericReflection; import greencode.util.GenericReflection.Condition; import greencode.util.StringUtils; import greencode.validator.DataValidation; final class ActionLoader { private ActionLoader() {} private final static Condition<Field> conditionAnnotationField = new GenericReflection.Condition<Field>() { public boolean init(Field f) { return f.isAnnotationPresent(RequestParameter.class) || f.isAnnotationPresent(SessionAttribute.class) || f.isAnnotationPresent(ViewSessionAttribute.class) || f.isAnnotationPresent(ConversationAttribute.class) || f.isAnnotationPresent(In.class) || f.isAnnotationPresent(UserPrincipal.class); } }; static void process(final GreenContext context, final HttpAction controller, final Method requestMethod) throws UnsupportedEncodingException, IllegalArgumentException, IllegalAccessException, SecurityException, InvocationTargetException, NoSuchMethodException { Field[] fields = GenericReflection.getDeclaredFieldsByConditionId(controller.getClass(), "httpAction:annotations"); if (fields == null) fields = GenericReflection.getDeclaredFieldsByCondition(controller.getClass(), "httpAction:annotations", conditionAnnotationField, true); for (Field f : fields) { Class<?> fieldType = f.getType(); if (f.isAnnotationPresent(In.class)) { In in = f.getAnnotation(In.class); final boolean isDiffConversation = in.conversationId() != Conversation.CURRENT && in.conversationId() != context.getRequest().getConversationId(); Conversation conversation = isDiffConversation ? greencode.http.$Conversation.getInstance(context.getRequest(), in.conversationId()) : context.getRequest().getConversation(); if (ClassUtils.isParent(fieldType, Window.class)) { f.set(controller, in.create() ? WindowHandle.getInstance((Class<Window>) fieldType, conversation) : greencode.jscript.dom.$Window.getMap(conversation).get(fieldType)); } } else if (f.isAnnotationPresent(RequestParameter.class)) { if (ClassUtils.isPrimitiveOrWrapper(fieldType)) { RequestParameter requestParameterAnnotation = f.getAnnotation(RequestParameter.class); String parametro = requestParameterAnnotation.value(); if (parametro.isEmpty()) parametro = f.getName(); Object value = context.request.getParameter(parametro); if (value != null) { value = fieldType.equals(String.class) ? StringUtils.toCharset((String) value, GreenCodeConfig.Server.View.charset) : GenericReflection.getDeclaredMethod(ClassUtils.toWrapperClass(fieldType), "valueOf", String.class).invoke(null, context.request.getParameter(parametro)); if (requestParameterAnnotation.trim()) value = ((String) value).trim(); if (requestParameterAnnotation.removeMultipleSpaces()) value = StringUtils.removeMultipleSpaces(((String) value)); f.set(controller, value); } else { f.set(controller, ClassUtils.getDefaultValue(fieldType)); } } /* * TODO: Verificar se será necessário isso no futuro. else * f.set(controller, * HttpParameter.Context.getObjectRequest(context * .request.getParameter(parametro))); */ } else if (f.isAnnotationPresent(SessionAttribute.class)) f.set(controller, context.request.getSession().getAttribute(f.getName())); else if (f.isAnnotationPresent(ViewSessionAttribute.class)) f.set(controller, context.request.getViewSession().getAttribute(f.getName())); else if (f.isAnnotationPresent(ConversationAttribute.class)) f.set(controller, context.request.getConversation().getAttribute(f.getName())); else if (f.isAnnotationPresent(UserPrincipal.class)) f.set(controller, context.request.getUserPrincipal()); } if (requestMethod.isAnnotationPresent(Validate.class)) { DataValidation data = new DataValidation(context, requestMethod.getAnnotation(Validate.class)); String classNameBootAction = null; if (Cache.bootAction != null) { classNameBootAction = Cache.bootAction.getClass().getSimpleName(); Console.log("Calling BeforeValidation: [" + classNameBootAction + "]"); Cache.bootAction.beforeValidation(data); } greencode.kernel.Validate.validate(context, requestMethod, context.requestedForm, null, data); if (Cache.bootAction != null) { Console.log("Calling AfterValidation: [" + classNameBootAction + "]"); Cache.bootAction.afterValidation(context.requestedForm, data); } data = null; } } public static DatabaseConnectionEvent connection(GreenContext context, Method requestMethod) throws SQLException, InstantiationException, IllegalAccessException { DatabaseConnectionEvent databaseConnectionEvent = null; if (requestMethod.isAnnotationPresent(Connection.class)) { Connection cA = requestMethod.getAnnotation(Connection.class); if (Cache.classDatabaseConnectionEvent == null) { Database.startConnection(context, cA); context.getDatabaseConnection().setAutoCommit(GreenCodeConfig.Server.DataBase.autocommit); if (!GreenCodeConfig.Server.DataBase.autocommit) { databaseConnectionEvent = new DatabaseConnectionEvent() { public void onSuccess(GreenContext context) { } public void beforeRequest(GreenContext context, Connection connection) { } public void onError(GreenContext context, Exception e) { try { context.getDatabaseConnection().rollback(); } catch (SQLException e1) { throw new RuntimeException(e1); } } public void afterRequest(GreenContext context) { try { if (greencode.database.$DatabaseConnection.hasError(context.getDatabaseConnection())) { context.getDatabaseConnection().rollback(); } else { context.getDatabaseConnection().commit(); } } catch (SQLException e) { throw new RuntimeException(e); } } }; } } else { databaseConnectionEvent = (DatabaseConnectionEvent) Cache.classDatabaseConnectionEvent.newInstance(); databaseConnectionEvent.beforeRequest(context, cA); } } return databaseConnectionEvent; } }