001: /*
002: * JFox - The most lightweight Java EE Application Server!
003: * more details please visit http://www.huihoo.org/jfox or http://www.jfox.org.cn.
004: *
005: * JFox is licenced and re-distributable under GNU LGPL.
006: */
007: package org.jfox.mvc;
008:
009: import java.lang.annotation.Annotation;
010: import java.lang.reflect.Array;
011: import java.lang.reflect.Field;
012: import java.lang.reflect.InvocationTargetException;
013: import java.util.Arrays;
014: import java.util.Collection;
015: import java.util.HashMap;
016: import java.util.Map;
017: import java.util.Set;
018:
019: import org.apache.log4j.Logger;
020: import org.jfox.mvc.validate.ValidateException;
021: import org.jfox.mvc.validate.Validators;
022: import org.jfox.util.ClassUtils;
023:
024: /**
025: * MVC Invocation
026: *
027: * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
028: */
029: public abstract class Invocation {
030:
031: /**
032: * å˜çš„原始数æ?®ï¼Œä»Ž HttpRequest.parameterMap å¤?制过æ?¥ï¼Œæ¯”如:对于 upload field,这里å˜çš„å?ªæ˜¯ filedname
033: * value 统一用数组ä¿?å˜ï¼Œè¿™æ ·å?¯ä»¥å¤„ç?† checkbox
034: */
035: private Map<String, String[]> attributes = new HashMap<String, String[]>();
036:
037: /**
038: * form ä¸éœ€è¦?有 <input type="hidden" name="request_token" value="$J_REQUESET_TOKEN">
039: */
040: private String request_token = null;
041:
042: private Logger logger = Logger.getLogger(this .getClass());
043:
044: public Invocation() {
045: // initValidationMap();
046: }
047:
048: /**
049: * 设置所有数æ?®ï¼Œå¹¶è¿›è¡Œæ ¡éªŒ
050: * @param fieldValidationMap fieldValidationMap
051: * @param parameterMap æ??交的 http request parameterMap
052: * @param fileUploadeds ä¸Šä¼ çš„æ–‡ä»¶
053: * @throws ValidateException valiate
054: * @throws InvocationException invocation
055: */
056: final void init(
057: Map<String, ActionSupport.FieldValidation> fieldValidationMap,
058: Map<String, String[]> parameterMap,
059: Collection<FileUploaded> fileUploadeds)
060: throws ValidateException, InvocationException {
061:
062: attributes.putAll(parameterMap);
063: // verify & build form field from parameterMap
064: ValidateException validateException = null;
065:
066: // �制一份
067: fieldValidationMap = new HashMap<String, ActionSupport.FieldValidation>(
068: fieldValidationMap);
069: for (Map.Entry<String, String[]> entry : parameterMap
070: .entrySet()) {
071: String key = entry.getKey();
072: String[] values = entry.getValue();
073: try {
074: ActionSupport.FieldValidation fieldValidation = fieldValidationMap
075: .remove(key);
076: if (fieldValidation == null) {
077: //仅仅�出一个信�
078: String msg = "Set invocation "
079: + this .getClass().getName() + "'s field \""
080: + key + "\" with value "
081: + Arrays.toString(values)
082: + " failed, No such filed!";
083: logger.warn(msg);
084: continue;
085: }
086: Field field = fieldValidation.getField();
087: field.setAccessible(true);
088: Annotation validationAnnotation = fieldValidation
089: .getValidationAnnotation();
090:
091: Class<?> fieldType = field.getType();
092: if (fieldType.isArray()) {
093: Class<?> arrayType = fieldType.getComponentType();
094: Object paramArray = Array.newInstance(arrayType,
095: values.length);
096: for (int i = 0; i < Array.getLength(paramArray); i++) {
097: if (validationAnnotation != null) {
098: try {
099: // valiate field input and construct
100: Array.set(paramArray, i, Validators
101: .validate(field, values[i],
102: validationAnnotation));
103: } catch (ValidateException e) {
104: // �记录第一个 ValidateException
105: if (validateException == null) {
106: validateException = e;
107: }
108: }
109: } else {
110: //no validator, try to use ClassUtils construct object
111: Array.set(paramArray, i, ClassUtils
112: .newObject(arrayType, values[i]));
113: // paramArray[i] = ClassUtils.newObject(arrayType, values[i]);
114: }
115: }
116: field.set(this , paramArray);
117: } else {
118: String value = values[0];
119: Object v = null;
120:
121: if (validationAnnotation != null) {
122: try {
123: v = Validators.validate(field, value,
124: validationAnnotation);
125: } catch (ValidateException e) {
126: // �记录第一个 ValidateException
127: if (validateException == null) {
128: validateException = e;
129: }
130: }
131: } else {
132: v = ClassUtils.newObject(fieldType, value);
133: }
134: field.set(this , v);
135: }
136: } catch (InvocationTargetException e) {
137: Throwable t = e.getTargetException();
138: String msg = "Set invocation + "
139: + this .getClass().getName() + "'s field \""
140: + key + "\" with value "
141: + Arrays.toString(values) + " failed!";
142: logger.error(msg, t);
143: throw new InvocationException(msg, t);
144: } catch (Throwable t) {
145: String msg = "Set invocation + "
146: + this .getClass().getName() + "'s field \""
147: + key + "\" with value "
148: + Arrays.toString(values) + " failed!";
149: logger.error(msg, t);
150: throw new InvocationException(msg, t);
151: }
152: }
153:
154: // 检查是�有必须的field还没有设置
155: for (ActionSupport.FieldValidation fieldValidation : fieldValidationMap
156: .values()) {
157: Annotation validationAnnotation = fieldValidation
158: .getValidationAnnotation();
159: if (validationAnnotation != null) {
160: if (!Validators
161: .isValidationNullable(validationAnnotation)) {
162: validateException = new ValidateException(
163: "input can not be null!", this .getClass()
164: .getName()
165: + "."
166: + fieldValidation.getField()
167: .getName(), null);
168: break;
169: }
170: }
171: }
172:
173: if (validateException != null) {
174: String msg = "Set invocation + "
175: + this .getClass().getName() + "'s field \""
176: + validateException.getInputField()
177: + "\" with value \""
178: + validateException.getInputValue() + "\" failed, "
179: + validateException.getMessage();
180: logger.error(msg);
181: throw validateException; // throw exception to execute()
182: }
183:
184: // build upload file field
185: for (FileUploaded fileUploaded : fileUploadeds) {
186: String fieldName = fileUploaded.getFieldname();
187: try {
188: Field field = ClassUtils.getDecaredField(this
189: .getClass(), fieldName);
190: field.setAccessible(true);
191: Class<?> fieldType = field.getType();
192: if (FileUploaded.class.isAssignableFrom(fieldType)) {
193: field.set(this , fileUploaded);
194: } else {
195: String msg = "Invocation "
196: + this .getClass().getName() + " 's field "
197: + field.getName() + " is not a type "
198: + FileUploaded.class.getName();
199: logger.warn(msg);
200: throw new InvocationException(msg);
201: }
202: } catch (NoSuchFieldException e) {
203: String msg = "Set invocation "
204: + this .getClass().getName()
205: + "'s FileUploaded field " + fieldName
206: + " with value " + fileUploaded + " failed!";
207: logger.warn(msg, e);
208: throw new InvocationException(msg, e);
209: } catch (IllegalAccessException e) {
210: String msg = "Set invocation "
211: + this .getClass().getName()
212: + "'s FileUploaded field " + fieldName
213: + " with value " + fileUploaded + " failed!";
214: logger.warn(msg, e);
215: throw new InvocationException(msg, e);
216: }
217: }
218: }
219:
220: public final Set<String> attributeKeys() {
221: return attributes.keySet();
222: }
223:
224: /**
225: * 返回数组
226: * @param key key
227: */
228: public final String[] getAttributeValues(String key) {
229: return attributes.get(key);
230: }
231:
232: /**
233: * 如果数组大于1,则返回数组,如果 ==1,返回第一个元ç´
234: * @param key key
235: */
236: public final Object getAttribute(String key) {
237: Object obj = attributes.get(key);
238: if (obj != null && obj.getClass().isArray()) {
239: Object[] objArray = (Object[]) obj;
240: if (objArray.length == 0) {
241: return null;
242: } else if (objArray.length == 1) {
243: return objArray[0];
244: } else {
245: return obj;
246: }
247: } else {
248: return obj;
249: }
250: }
251:
252: public final String getRequestToken() {
253: return request_token;
254: }
255:
256: public final void setRequestToken(String requestToken) {
257: this .request_token = requestToken;
258: }
259:
260: /**
261: * 对应的 @ActionMethod name
262: * @throws ValidateException validate exception
263: */
264: public void validateAll() throws ValidateException {
265:
266: }
267:
268: public String toString() {
269: // 实现 toString,便于日志记录
270: StringBuffer sb = new StringBuffer();
271: sb.append("{");
272: int i = 0;
273: for (Map.Entry<String, String[]> entry : attributes.entrySet()) {
274: String key = entry.getKey();
275: if (i > 0) {
276: sb.append(",");
277: }
278: sb.append(key).append("=");
279: String[] value = entry.getValue();
280: if (value == null) {
281: sb.append("null");
282: } else if (value.length == 0) {
283: sb.append("");
284: } else if (value.length == 1) {
285: sb.append(value[0]);
286: } else {
287: sb.append(Arrays.toString(value));
288: }
289: i++;
290: }
291: sb.append("}");
292: return sb.toString();
293: }
294:
295: public static void main(String[] args) {
296:
297: }
298: }
|