1 package org.cateproject.controller.flow.action;
2
3 import java.util.Set;
4
5 import javax.validation.ConstraintViolation;
6 import javax.validation.Validator;
7 import javax.validation.groups.Default;
8
9 import org.apache.log4j.Logger;
10 import org.springframework.beans.BeansException;
11 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.beans.factory.annotation.Qualifier;
13 import org.springframework.binding.message.Message;
14 import org.springframework.binding.message.MessageBuilder;
15 import org.springframework.binding.message.MessageContext;
16 import org.springframework.context.ApplicationContext;
17 import org.springframework.context.ApplicationContextAware;
18 import org.springframework.webflow.execution.RequestContext;
19
20 import eu.etaxonomy.cdm.api.service.IIdentifiableEntityService;
21 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
22 import eu.etaxonomy.cdm.validation.Level2;
23 import eu.etaxonomy.cdm.validation.Level3;
24
25 public abstract class AbstractFlowAction<T extends IdentifiableEntity,SERVICE extends IIdentifiableEntityService<T>> implements ApplicationContextAware {
26 protected static Logger logger = Logger.getLogger(AbstractFlowAction.class);
27
28 protected SERVICE service;
29 protected ApplicationContext applicationContext;
30 public static String WEBFLOW_SESSION_MESSAGE_KEY = "org.cateproject.controller.flow.action.AbstractEditAction.message";
31
32 protected Validator validator;
33
34 public abstract void setService(SERVICE service);
35
36 public abstract boolean validate(T object, MessageContext messageContext);
37
38 @Autowired
39 @Qualifier("validatorFactory")
40 public void setValidator(Validator validator) {
41 this.validator = validator;
42 }
43
44 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
45 this.applicationContext = applicationContext;
46 }
47
48 public void addMessage(MessageContext messageContext, String source, String code, String defaultMessage) {
49 logger.error("Global Error: " + source + " " + defaultMessage);
50 messageContext.addMessage(new MessageBuilder().error().source(source).code(code).defaultText(defaultMessage).build());
51 }
52
53 public boolean leaveMessage(String message, RequestContext requestContext) {
54 requestContext.getExternalContext().getSessionMap().put(AbstractEditAction.WEBFLOW_SESSION_MESSAGE_KEY, message);
55 return Boolean.TRUE;
56 }
57
58 protected <U> boolean validatateAtLevel(U object, Class<?> level, MessageContext messageContext, Set<String> propertiesToIgnore, String prefix) {
59 Boolean valid = true;
60 Set<ConstraintViolation<U>> result = this.validator.validate(object, level);
61 for (ConstraintViolation<U> violation : result) {
62 if(propertiesToIgnore != null && propertiesToIgnore.contains(violation.getPropertyPath().toString())) {
63 logger.info("IGNORING Property Error: " + violation.getPropertyPath().toString() + " " + violation.getMessage());
64 } else {
65 addConstraintViolationToMessageContext(violation,messageContext,propertiesToIgnore, prefix);
66 valid = false;
67 }
68 }
69 return valid;
70 }
71
72 public <U> boolean validateIgnoringProperties(U object, MessageContext messageContext, Set<String> propertiesToIgnore, String prefix) {
73 Boolean valid = true;
74
75 valid = validatateAtLevel(object,Default.class,messageContext,propertiesToIgnore, prefix);
76 logger.info("Validating object at default level " + valid);
77 if(valid) {
78 valid = validatateAtLevel(object,Level2.class,messageContext,propertiesToIgnore, prefix);
79 logger.info("Validating object at level 2 " + valid);
80 }
81
82 if(valid) {
83 valid = validatateAtLevel(object,Level3.class,messageContext,propertiesToIgnore, prefix);
84 logger.info("Validating object at level 3 " + valid);
85 }
86 logger.info("Validated object returning " + valid + " " + messageContext.getAllMessages().length + " messages");
87 for(Message m : messageContext.getAllMessages()) {
88 logger.info("\t" + m.getText() + " (" + m.getSource() + ")");
89 }
90 return valid;
91 }
92
93 public <U> void addConstraintViolationToMessageContext(ConstraintViolation<U> violation, MessageContext messageContext, Set<String> propertiesToIgnore, String prefix) {
94
95 if(violation.getPropertyPath().toString() != null && violation.getPropertyPath().toString().length() > 0) {
96 logger.error("Property Error: " + violation.getPropertyPath().toString() + " " + violation.getMessage());
97 if(prefix == null || prefix == "") {
98 messageContext.addMessage(new MessageBuilder().error()
99 .source(violation.getPropertyPath().toString())
100 .code(violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName())
101 .args(violation.getConstraintDescriptor().getAttributes().values().toArray())
102 .defaultText(violation.getMessage()).build());
103 } else {
104 messageContext.addMessage(new MessageBuilder().error()
105 .source(prefix + '.' + violation.getPropertyPath().toString())
106 .code(violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName())
107 .args(violation.getConstraintDescriptor().getAttributes().values().toArray())
108 .defaultText(violation.getMessage()).build());
109 }
110 } else {
111 logger.error("Global Error: " + violation.getPropertyPath().toString() + " " + violation.getMessage());
112 if(prefix == null || prefix == "") {
113 messageContext.addMessage(new MessageBuilder().error()
114 .code(violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName())
115 .args(violation.getConstraintDescriptor().getAttributes().values().toArray())
116 .defaultText(violation.getMessage()).build());
117 } else {
118 messageContext.addMessage(new MessageBuilder().error()
119 .source(prefix)
120 .code(violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName())
121 .args(violation.getConstraintDescriptor().getAttributes().values().toArray())
122 .defaultText(violation.getMessage()).build());
123 }
124 }
125 }
126
127 }