View Javadoc

1   /*
2    * ConstraintContainer.java
3    * Created on 14 Октябрь 2006 г., 20:43
4    */
5   
6   package org.weda.property.impl;
7   
8   import java.lang.reflect.InvocationTargetException;
9   import java.lang.reflect.Method;
10  import org.weda.converter.ValueTypeConverter;
11  import org.weda.enhance.InjectHivemindObject;
12  import org.weda.enhance.InjectMessages;
13  import org.weda.message.Messages;
14  import org.weda.property.Constraint;
15  import org.weda.property.ConstraintException;
16  
17  /**Ограничение которое при проверке 
18   * (вызове метода {@link org.weda.property.Constraint#check(Object, Object[])})
19   * вызывает метод объекта переданного в конструкторе.
20   *
21   * @author Mikhail Titov
22   */
23  public class ConstraintContainer implements Constraint{
24      private final static String ERROR_MESSAGE_KEY = "errorMessage";
25      
26      private Object constraint;
27      private ConstraintCheckMethod[] checkMethods;
28      private ConstraintCheckMethod defaultCheckMethod;
29      private String constraintId;
30      @InjectMessages()
31      private Messages messages;
32      @InjectHivemindObject()
33      private static ValueTypeConverter converter;
34      
35      public ConstraintContainer(
36              String constraintId, Object constraint
37              , ConstraintCheckMethod[] checkMethods
38              , ConstraintCheckMethod defaultCheckMethod) 
39      {         
40          this.constraintId = constraintId;
41          this.constraint = constraint;
42          this.checkMethods = checkMethods;
43          this.defaultCheckMethod = defaultCheckMethod;
44      }
45  
46      public void check(Object value, Object[] parameters) 
47          throws ConstraintException 
48      {
49          try {
50              if (value == null)
51                  return;
52              Class type = value.getClass();
53              ConstraintCheckMethod checkMethod = getCheckMethod(type);
54              if (   checkMethod == defaultCheckMethod 
55                  && !checkMethod.getValueType().isAssignableFrom(type))
56              {
57                  value = converter.convert(
58                              checkMethod.getValueType(), value, null);
59              }
60  
61              Object[] methodParameters = 
62                      new Object[checkMethod.getParameterTypes().length+1];
63              methodParameters[0] = value;
64              System.arraycopy(
65                      parameters, 0, methodParameters, 1, parameters.length);
66              checkMethod.getCheckMethod().invoke(constraint, methodParameters);
67          } catch (Throwable e) {
68              if (e instanceof InvocationTargetException){
69                  InvocationTargetException ie = (InvocationTargetException)e;
70                  if (ie.getCause() instanceof ConstraintException)
71                      throw (ConstraintException)ie.getCause();
72              }                
73              throw new ConstraintException(
74                          messages.getMessage(ERROR_MESSAGE_KEY), e);
75          } 
76      }
77  
78      public Class[] getParameterTypes(Class valueType) 
79          throws ConstraintException
80      {
81          return getCheckMethod(valueType).getParameterTypes();
82      }
83  
84      public String getId() {
85          return constraintId;
86      }
87      
88      private ConstraintCheckMethod getCheckMethod(Class valueType)
89          throws ConstraintException 
90      {        
91          ConstraintCheckMethod checkMethod = null;
92          for (ConstraintCheckMethod method: checkMethods)
93              if (method.getValueType().isAssignableFrom(valueType)){
94                  checkMethod = method;
95                  break;
96              }
97          if (checkMethod == null)
98              checkMethod = defaultCheckMethod;
99          if (checkMethod == null)
100             throw new ConstraintException(
101                     String.format(
102                         "Check error in constraint (%s). " +
103                         "Can't find check method for value type (%s)"
104                         , constraintId, valueType.getName()));
105         return checkMethod;
106     }
107     
108 }