001: package org.vraptor.component;
002:
003: import java.lang.reflect.Method;
004: import java.lang.reflect.Modifier;
005: import java.util.HashMap;
006: import java.util.List;
007: import java.util.Map;
008:
009: import org.apache.log4j.Logger;
010: import org.vraptor.ValidationErrorsFactory;
011: import org.vraptor.annotations.Logic;
012: import org.vraptor.reflection.ReflectionUtil;
013: import org.vraptor.validator.ValidationErrors;
014: import org.vraptor.webapp.DefaultComponentManager;
015:
016: /**
017: * Factory for logic methods.
018: *
019: * @author Guilherme Silveira
020: */
021: public class DefaultLogicMethodFactory implements LogicMethodFactory {
022:
023: private static final Logger LOG = Logger
024: .getLogger(DefaultLogicMethodFactory.class);
025: private final ValidationErrorsFactory validationFactory;
026: private final ParameterInfoProvider paramInfo;
027:
028: public DefaultLogicMethodFactory(
029: ValidationErrorsFactory validationFactory,
030: ParameterInfoProvider paramInfoProvider) {
031: this .validationFactory = validationFactory;
032: this .paramInfo = paramInfoProvider;
033: }
034:
035: public Map<String, DefaultLogicMethod> loadLogics(Class<?> type)
036: throws InvalidComponentException {
037: Map<String, DefaultLogicMethod> actions = new HashMap<String, DefaultLogicMethod>();
038: for (Method m : type.getMethods()) {
039: if (isNotLogicMethod(m)) {
040: LOG.debug("ignoring method " + m + " as logic!");
041: continue;
042: }
043: Logic annotation = m.getAnnotation(Logic.class);
044: generateLogics(actions, m, annotation, type);
045: }
046: return actions;
047: }
048:
049: private boolean isNotLogicMethod(Method m) {
050: return !Modifier.isPublic(m.getModifiers())
051: || Modifier.isStatic(m.getModifiers())
052: || m.getDeclaringClass().equals(Object.class)
053: || m
054: .getName()
055: .startsWith(
056: DefaultComponentManager.VALIDATE_METHOD_INITIALS)
057: || ReflectionUtil.isGetter(m);
058: }
059:
060: private void generateLogics(
061: Map<String, DefaultLogicMethod> actions, Method method,
062: Logic annotation, Class<?> type)
063: throws InvalidComponentException {
064: if (annotation == null || annotation.value().length == 0) {
065: register(actions, create(method.getName(), type, method));
066: } else {
067: for (String name : annotation.value()) {
068: register(actions, create(name, type, method));
069: }
070: }
071: }
072:
073: private void register(Map<String, DefaultLogicMethod> actions,
074: DefaultLogicMethod action) {
075: if (LOG.isDebugEnabled()) {
076: LOG.debug("Registering logic " + action.getName());
077: }
078: actions.put(action.getName(), action);
079: }
080:
081: public DefaultLogicMethod create(String name, Class<?> type,
082: Method method) throws InvalidComponentException {
083: if (name.indexOf('.') != -1) {
084: throw new InvalidComponentException(
085: "Type "
086: + type.getName()
087: + " method "
088: + method.getName()
089: + " contains invalid logic with name containing a dot.");
090: }
091: Method validateMethod = ReflectionUtil.getPrefixedMethod(type,
092: "validate", name, addValidationErrorsToArray(method));
093: List<MethodParameter> parameters = paramInfo.provideFor(method);
094: return new DefaultLogicMethod(validationFactory, name, method,
095: validateMethod, parameters);
096: }
097:
098: private Class[] addValidationErrorsToArray(Method method) {
099:
100: Class[] types = new Class[method.getParameterTypes().length + 1];
101: types[0] = ValidationErrors.class;
102: int i = 1;
103: for (Class type : method.getParameterTypes()) {
104: types[i++] = type;
105: }
106: return types;
107: }
108: }
|