View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2012-2-16 下午03:34:12
4    */
5   package gboat2.base.core.web;
6   
7   import gboat2.base.bridge.util.ClassHelper;
8   import gboat2.base.core.GBoatClassLoader;
9   import gboat2.base.core.annotation.DateFormat;
10  import gboat2.base.core.dao.Page;
11  import gboat2.base.core.dao.PageBean;
12  import gboat2.base.core.model.Opera;
13  import gboat2.base.core.service.IBaseService;
14  import gboat2.base.core.service.IOperationProvider;
15  import gboat2.base.core.service.ModuleService;
16  import gboat2.base.core.util.ActionUtil;
17  import gboat2.base.core.util.EnumTypeUtils;
18  import gboat2.base.core.util.EnumTypeWrapper;
19  import gboat2.base.core.util.JsonConfigUtil;
20  import gboat2.base.core.util.JsonUtil;
21  import gboat2.base.core.util.json.GboatJsonDateValueProcessor;
22  import gboat2.base.core.validate.PrivilegeCheckServiceFactory;
23  import gboat2.base.core.web.md.MetadataSupport;
24  
25  import java.beans.PropertyDescriptor;
26  import java.lang.reflect.Field;
27  import java.lang.reflect.InvocationTargetException;
28  import java.lang.reflect.Method;
29  import java.text.SimpleDateFormat;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.HashMap;
33  import java.util.Iterator;
34  import java.util.LinkedList;
35  import java.util.List;
36  import java.util.Map;
37  
38  import javax.persistence.Enumerated;
39  
40  import net.sf.json.JSONArray;
41  import net.sf.json.JSONObject;
42  import net.sf.json.JsonConfig;
43  
44  import org.apache.commons.beanutils.PropertyUtils;
45  import org.apache.commons.collections.CollectionUtils;
46  import org.apache.commons.lang3.StringUtils;
47  import org.osgi.framework.Bundle;
48  import org.osgi.framework.BundleContext;
49  import org.osgi.framework.FrameworkUtil;
50  import org.osgi.framework.ServiceReference;
51  import org.slf4j.Logger;
52  import org.slf4j.LoggerFactory;
53  import org.springframework.util.Assert;
54  import org.springframework.util.ReflectionUtils;
55  
56  import com.opensymphony.xwork2.ActionSupport;
57  
58  /**
59   * 
60   * 视图定义元数据处理类,根据定义元数据处理成符合前后台交互的元数据要求
61   * @author lysming
62   * @since jdk1.6
63   * @date 2012-2-16
64   *  
65   */
66  
67  public abstract class MetadataSupportStrategy {
68  	protected final static String FILTER_PARAMS = "filter_params_";
69  	protected final static String DEFINED_OPERATIONS = "defined_operations_";
70  	
71  	//获得logger
72  	protected static Logger logger = LoggerFactory.getLogger(MetadataSupportStrategy.class);
73  
74  	//缓存类所对应的枚举类,在内存中缓存,由于是共享变量,因此此属性非线程不安全:enumsInClass
75  	static Map<Class<?>, List<Class<?>>> enumsInClass = new HashMap<Class<?>, List<Class<?>>>();
76  
77  	/**抽象方法:可以不同的需求实现不同策略
78  	 * @param metadataType
79  	 * @param invokeMethod
80  	 * @param action
81  	 * @return
82  	 */
83  	abstract Object getMetadata(String metadataType, String invokeMethod, BaseActionSupport action);
84  
85  	/**
86  	 * 
87  	 * 通过全部元数据json对象获取当前请求组件名称定义
88  	 * @author zhaoxc
89  	 * @since jdk1.6
90  	 * @date 2012-5-23
91  	 *  
92  	 */
93  	public JSONObject getMetadataFromResource(String invokeMethod, BaseActionSupport action) {
94  		JSONObject jObj = MetadataSupport.parseMetadata(invokeMethod, action);
95  		if (jObj == null) {
96  			jObj = new JSONObject();
97  			jObj.accumulate("success", false);
98  			jObj.accumulate("message", "failed to read metadata for " + action.getClass().getName());
99  		}
100 
101 		return jObj;
102 	}
103 
104 	/**
105 	 * 
106 	 * 通过全部元数据json对象获取当前请求组件内容定义
107 	 * @author zhaoxc
108 	 * @since jdk1.6
109 	 * @date 2012-5-23
110 	 * @update by zhangxj-a 
111 	 */
112 	public JSONObject decorateMetadata(JSONObject returned, String invokeMethod, BaseActionSupport action) {
113 		SplitMetadataStrategy splitMetadataStrategy;
114 		if (ActionUtil.isListPage(invokeMethod, action)) {//列表页面
115 			splitMetadataStrategy = MetadataList.getInstance();
116 		} else if (ActionUtil.isFormPage(invokeMethod, action)) {//表单页面
117 			splitMetadataStrategy = MetadataEdit.getInstance();
118 		} else {//其他页面
119 			splitMetadataStrategy = MetadataOthers.getInstance();
120 		}
121 		return splitMetadataStrategy.decorateMetadata(returned, invokeMethod, action);
122 	}
123 
124 	/**
125 	 * 
126 	 * 通过全部元数据json对象获取当前请求组件数据定义
127 	 * @param calledInvokeMethod invokedMethod是否已经调用过
128 	 * @param metadata 元数据对象
129 	 * @param invokeMethod	调用方法名
130 	 * @param action action实例
131 	 * @param returned 返回的json对象
132 	 * @author zhaoxc
133 	 * @since jdk1.6
134 	 * @date 2012-5-23
135 	 *  
136 	 */
137 	public JSONObject decorateWithData(boolean calledInvokeMethod, JSONObject metadata, String invokeMethod, BaseActionSupport action,
138 			JSONObject returned) {
139 		JsonConfig jsonConf;
140 		Class<?> checkClazz;
141 		//列表页面,init和post方法需要特殊处理
142 		if (ActionUtil.isListPage(invokeMethod, action)) {
143 			Bundle bundle = FrameworkUtil.getBundle(action.getClass());
144 			
145 			//首先获取所有可能的操作
146 			List<Opera> operaList;
147 			//TODO 修改为Declare Service模式
148 			BundleContext context = bundle.getBundleContext();
149 			ServiceReference<?> sf = context.getServiceReference(IOperationProvider.class);
150             if (sf != null) {
151                 // 获取到对应模块下的所有操作
152                 IOperationProvider provider = (IOperationProvider) context.getService(sf);
153                 List<Opera> moduleOperaList = provider.getOperations(action);
154                 // 在 JSP 页面中定义的操作(逗号分隔)
155                 String definedOperationsStr = action.request.getParameter(DEFINED_OPERATIONS);
156                 
157                 if(StringUtils.isBlank(definedOperationsStr) || CollectionUtils.isEmpty(moduleOperaList)) {
158 //                    operaList = new ArrayList<Opera>();
159                     operaList = moduleOperaList;
160                 } else {
161                     String[] definedOperations = StringUtils.split(definedOperationsStr, ',');
162                     operaList = new ArrayList<Opera>(definedOperations.length);
163                     // 根据 JSP 页面中定义的操作与模板下的所有操作逐一进行比对(为了保证按钮的显示顺序与定义顺序一致,所以先对 definedOperations 进行迭代)
164                     for (String code : definedOperations) {
165                         for (Opera opera : moduleOperaList) {
166                             if(StringUtils.equals(StringUtils.trim(code), StringUtils.trim(opera.getCode()))) {
167                                 operaList.add(opera);
168                                 break;
169                             }
170                         }
171                     }
172                 }
173             } else {
174                 operaList = ModuleService.getOperaForMetadata(bundle.getSymbolicName(), action.getClass().getName());
175             }
176             
177 			jsonConf = JsonConfigUtil.getJsonConfig(EnumTypeUtils.getEnumClassInDomain(action.getDomainClassAnnotationedForList()));
178 			if (!calledInvokeMethod) {
179 				try {
180 					Method method = ReflectionUtils.findMethod(action.getClass(), invokeMethod);
181 					if (method != null) {
182 						ReflectionUtils.makeAccessible(method);
183 						method.invoke(action, new Object[] {});
184 					} else {
185 						action.executeListQuery(action.getListParameterMap());
186 					}
187 				} catch (Exception e) {
188 					throw new MetadataException(e);
189 				}
190 			}
191 			Page<?> page = action.getPage();
192 
193 			//call postXXXX方法
194 			String postMethodName = ActionUtil.getPostMethodName(invokeMethod);
195 			//postList在BaseActionSupport的list方法中默认调用,该处不需要重复调用
196 			if (!postMethodName.equals("postList")) {
197 				try {
198 					Method postListMethod = ReflectionUtils.findMethod(action.getClass(), postMethodName, new Class[] { Page.class });
199 					if (null != postListMethod) {
200 						ReflectionUtils.makeAccessible(postListMethod);
201 						postListMethod.invoke(action, page);
202 					}
203 				} catch (Exception e) {
204 					throw new MetadataException(e);
205 				}
206 			}
207 
208 			List<?> items = page.getResult();
209 			JSONArray jsonObjs = new JSONArray();
210 			List<Opera> priviArray = getOperationByPriviledge(operaList, action);
211 			for (Object item : items) {
212 				JSONObject finalObj = null;
213 				if(StringUtils.isNotEmpty(action.request.getParameter(FILTER_PARAMS))){
214 					//根据页面传递的过滤参数定义过滤数据
215 					finalObj = filterDataByParam(item, action);
216 				}else{
217 					//根据元文件过滤数据
218 					finalObj = filterDataByMetadata(metadata, item, action);
219 				}
220 				if(finalObj != null){
221 					//将操作添加给每条数据,并提前进行权限过滤
222 					finalObj.accumulate("operations", getOperationByData(priviArray, action, item));
223 					jsonObjs.add(finalObj);
224 				}
225 			}
226 			
227             returned.accumulate("success", true);
228 			returned.accumulate("data", jsonObjs);       // 实际数据的数组
229 			PageBean pb = page.getPageBean();
230 			returned.accumulate("results", pb.getCount());
231 			returned.accumulate("total", pb.getPages()); // 总页数
232 			returned.accumulate("page", pb.getPage());   // 当前页的页码
233 		} else {
234 			jsonConf = JsonConfigUtil.getJsonConfig(EnumTypeUtils.getEnumClassInDomain(action.getDomainClassAnnotationed()));
235 			checkClazz = action.getClass();
236 			Method ajaxMethod, initMethod;
237 			ajaxMethod = ReflectionUtils.findMethod(checkClazz, invokeMethod);
238 			initMethod = ReflectionUtils.findMethod(checkClazz, ActionUtil.getInitMethodName(invokeMethod));
239 			if (ajaxMethod == null && initMethod == null) {
240 				returned.accumulate("success", false);
241 				returned.accumulate("message", "can't get method[" + invokeMethod + "] for " + action.getClass().getName());
242 			} else {
243 				try {
244 					if (!calledInvokeMethod && ajaxMethod != null) {
245 						ReflectionUtils.makeAccessible(ajaxMethod);
246 						ajaxMethod.invoke(action);
247 					}
248 					returned.accumulate("success", true);
249 					/** 如果不是backfill回填数据则不传回data** start*/
250 					boolean isAddData = true;
251 					JSONObject jso = (JSONObject) metadata.get("cfg");
252 					if (jso != null && !"request".equals(jso.get("backfill"))) {
253 						isAddData = false;
254 					}
255 					if (isAddData) {
256 						Map<String, Object> models = new HashMap<String, Object>();
257 						List<Object> result = new ArrayList<Object>();
258 						addGetDataToModels(action, action.getClass(), models);
259 						result.add(models);
260 						returned.accumulate("data", result.toArray(), jsonConf);
261 					}
262 					/**如果不是backfill回填数据则不传回data** end */
263 
264 				} catch (InvocationTargetException e) {
265 					logger.warn("error in get data", e);
266 					returned.accumulate("success", false);
267 					Throwable throwable = e.getTargetException();
268 					String message = null;
269 					if (throwable != null) {
270 						message = throwable.getMessage();
271 					}
272 					returned.accumulate("message", "error: " + message);
273 				} catch (Exception e) {
274 					logger.warn("error in get data", e);
275 					returned.accumulate("success", false);
276 					returned.accumulate("message", "error while get data : " + e.getMessage());
277 				}
278 			}
279 		}
280 		return returned;
281 	}
282 
283 	/**
284 	 * 根据请求传回的过滤参数过滤数据中不需要的数据,减少数据传输压力,为jsp页面的list数据请求服务
285 	 * 传递的参数名称为_filter_params,值为逗号分隔
286 	 * @param data
287 	 * @param action
288 	 * @return JSONObject对象
289 	 */
290 	private JSONObject filterDataByParam(Object data, BaseActionSupport action){
291 		String filterParams = action.request.getParameter(FILTER_PARAMS);
292 		String[] params = filterParams.split(",");
293 		List<String> toCompare = Arrays.asList(params);
294 		
295 		JsonConfig jsonConf = JsonConfigUtil.getJsonConfig(EnumTypeUtils.getEnumClassInDomain(action.getDomainClassAnnotationedForList()));
296 		
297 		return filter(data, toCompare, action, jsonConf);
298 	}
299 	
300 	/**
301 	 * 根据模板JSONObject,过滤数据中不需要的数据,这样可以减少网络压力 for list
302 	 * @param metadata 模板JSONObject
303 	 * @param data 数据object
304 	 * @return JSONObject对象
305 	 */
306 	private JSONObject filterDataByMetadata(JSONObject metadata, Object data, BaseActionSupport action) {
307 		//对列表中的枚举类型进行转换,变为json对象的形式
308 		JsonConfig jsonConf = JsonConfigUtil.getJsonConfig(EnumTypeUtils.getEnumClassInDomain(action.getDomainClassAnnotationedForList()));
309 		JSONObject returnJSONObj = new JSONObject();
310 		List<String> toCompare = new LinkedList<String>();
311 		if (null != metadata) {
312 			//TODO 该部分可以按照md进行缓存
313 			JSONArray headers = (JSONArray) metadata.get("headers");
314 			if (null != headers) {
315 				Iterator<?> headerItera = headers.iterator();
316 				//可优化减少循环次数
317 				while (headerItera.hasNext()) {
318 					JSONObject tempObj = (JSONObject) headerItera.next();
319 					//则设置日期字段该格式为自定义的格式
320 					String dateFormat = (String) tempObj.get("dateFormat");
321 					if (!StringUtils.isEmpty(dateFormat)) {
322 						jsonConf.registerJsonValueProcessor((String) tempObj.get("dataIndex"), new GboatJsonDateValueProcessor(dateFormat));
323 					}
324 				}
325 				String dataIndexObj;
326 				Iterator<?> hIt = headers.iterator();
327 				while (hIt.hasNext()) {
328 					JSONObject tempObj = (JSONObject) hIt.next();
329 					dataIndexObj = (String) tempObj.get("dataIndex");
330 					if (!StringUtils.isEmpty(dataIndexObj) && !toCompare.contains(dataIndexObj)) {
331 						toCompare.add(dataIndexObj);
332 					}
333 				}
334 			}
335 			
336 			returnJSONObj = filter(data, toCompare, action, jsonConf);
337 		}
338 		return returnJSONObj;
339 	}
340 	
341 	private JSONObject filter(Object data,List<String> toCompare,BaseActionSupport action,JsonConfig jsonConf){
342 		JSONObject returnJSONObj = new JSONObject();
343 		if(toCompare!=null && toCompare.size()>0){
344 			//解析数据成json
345 			JSONObject dataObj = JSONObject.fromObject(data, jsonConf);
346 			JSONObject translatedObj;
347 			Object value;
348 			String dataIndexObj;
349 			Iterator<?> hIt = toCompare.iterator();
350 			while (hIt.hasNext()) {
351 				dataIndexObj = (String) hIt.next();
352 				if (!StringUtils.isEmpty(dataIndexObj)) {
353 					value = dataObj.get(dataIndexObj);
354 					if(value!=null){
355 						translatedObj = JsonUtil.translateJSONOjbject(dataIndexObj, dataObj);
356 						returnJSONObj.accumulate(dataIndexObj, translatedObj.get(dataIndexObj));
357 					}
358 				}
359 			}
360 		}else{
361 			returnJSONObj = JSONObject.fromObject(data, jsonConf);
362 		}
363 		
364 		return returnJSONObj;
365 	}
366 
367 	private void addGetDataToModels(BaseActionSupport action, Class<?> actionClass, Map<String, Object> models) {
368 		getActionPropertiesValues(action, models, Boolean.FALSE);
369 	}
370 
371 	/**
372 	 * 获取list中每条数据应该具有的操作
373 	 * @param opera opera
374 	 * @param action 当前action
375 	 * @param data 被转换对象
376 	 * @return JSONArray数据
377 	 */
378 	private JSONArray getOperationByData(List<Opera> priviArray, BaseActionSupport action, Object data) {
379 		//1、获取数据操作判断方法
380 		Method getOperMethod = ReflectionUtils.findMethod(action.getClass(), "operationCheck", new Class[] { data.getClass(), String.class });
381 		if (getOperMethod == null) {
382 			getOperMethod = ReflectionUtils.findMethod(action.getClass(), "operationCheck", new Class[] { Object.class, String.class });
383 		}
384 
385 		Iterator<Opera> it = priviArray.iterator();
386 		List<String> operList = new ArrayList<String>();
387 		Opera opera;
388 		while (it.hasNext()) {
389 			opera = (Opera) it.next();
390 			String operCode = opera.getCode();
391 			if ("sumbit".equals(operCode) || "add".equals(operCode)) {
392 				continue;
393 			}
394 			if (!StringUtils.isEmpty(operCode)) {
395 
396 				//2、执行数据操作判断方法(根据数据状态决定是否有某个操作)
397 				boolean dataOperation = false;
398 				if (null != getOperMethod) {
399 					dataOperation = (Boolean) ReflectionUtils.invokeMethod(getOperMethod, action, new Object[] { data, operCode });
400 				}
401 				//只有list中的该条数据允许,才可以添加该操作
402 				if (dataOperation) {
403 					operList.add(operCode);
404 				}
405 			}
406 		}
407 
408 		JSONArray returnJSONObj = JSONArray.fromObject(operList);
409 		return returnJSONObj;
410 	}
411 
412 	/**
413 	 * 调用initXXXXX方法
414 	 * @param invokeMethod
415 	 * @param action
416 	 * @return
417 	 */
418 	protected boolean callInitInvokedMethod(String invokeMethod, BaseActionSupport action) {
419 	    Assert.hasText(invokeMethod, "被调用的方法不能为空!");
420 	    
421 		// 调用实际方法时会再次调用 init 方法
422 		if ("edit".equals(invokeMethod) || "view".equals(invokeMethod) || "list".equals(invokeMethod)) {
423 			// 如果子类覆盖了edit、view或list方法,依然执行initXXXX方法,否则不执行(BaseActionSupport中会显式调用)
424 			try {
425 				Method method = action.getClass().getDeclaredMethod(invokeMethod, new Class[] {});
426 				if (method == null) {
427 					return false;
428 				}
429 			} catch (Exception ignore) {
430 				//ignore the exception
431 				return false;
432 			}
433 		}
434 	
435 		String initMethodName = ActionUtil.getInitMethodName(invokeMethod);
436 		try {
437 			Method initMethod;
438             if (ActionUtil.isListPage(invokeMethod, action)) { // 列表查询的 initXxx() 方法有一个 Map 类型的参数
439                 // 检查是否存在带Map参数的init方法
440                 initMethod = ReflectionUtils.findMethod(action.getClass(), initMethodName, new Class[] { Map.class });
441                 if (initMethod != null) {
442                     ReflectionUtils.makeAccessible(initMethod);
443                     initMethod.invoke(action, action.getListParameterMap());
444                     return true;
445                 }
446             } else { // 非列表查询的 initXxx() 方法没有参数
447                 initMethod = ReflectionUtils.findMethod(action.getClass(), initMethodName);
448                 if (null != initMethod) {
449                     ReflectionUtils.makeAccessible(initMethod);
450                     ReflectionUtils.invokeMethod(initMethod, action);
451                     return true;
452                 }
453             }
454 		} catch (SecurityException e) {
455 			e.printStackTrace();
456 		} catch (Exception e) {
457 			e.printStackTrace();
458 		}
459 		return false;
460 	}
461 	
462 	/**
463 	 * 获取action中所有属性
464 	 * @param action
465 	 * @return
466 	 */
467 	public Map<String, Object> getActionParam(BaseActionSupport action) {
468 		Map<String, Object> params = new HashMap<String, Object>();
469 		//获取action中定义的属性
470 		params = getActionPropertiesValues(action, params, Boolean.TRUE);
471 
472 		//检查Domain中的enum,将enum自动添加到context中 
473 		List<Class<?>> toWrapper = new LinkedList<Class<?>>();
474 
475 		try {
476 			if (action.getDomainClassAnnotationed() != null) {
477 				toWrapper.add(action.getDomainClassAnnotationed());
478 			}
479 		} catch (Exception ignore) {
480 			//ignore
481 		}
482 		try {
483 			Class<?> listDomainClass = action.getDomainClassAnnotationedForList();
484 			while (listDomainClass != null && listDomainClass != Object.class) {
485 				if (!toWrapper.contains(listDomainClass)) {
486 					toWrapper.add(listDomainClass);
487 				}
488 				listDomainClass = listDomainClass.getSuperclass();
489 			}
490 			params.putAll(getEnumWrappers(toWrapper));
491 		} catch (Exception ignore) {
492 			//ignore
493 		}
494 
495 		//注册一些特殊的枚举类
496 		EnumTypeUtils.registerEnumClass(action, params);
497 
498 		return params;
499 	}
500 
501 	/**
502 	 * @param action
503 	 * @param actionPropertiesValues
504 	 * @param isVelocityFill :是否借助velocity填充数据,true:velocity填充;false:前台自己填充
505 	 * @return
506 	 */
507 	public Map<String, Object> getActionPropertiesValues(BaseActionSupport action, Map<String, Object> actionPropertiesValues, boolean isVelocityFill) {
508 		//private与getter同时存在才添加为action param 注意:此方法和addGetDataToModels很多重复代码,待重构
509 		PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(action);
510 		List<PropertyDescriptor> asList = Arrays.asList(propertyDescriptors);
511 
512 		Map<String, Method> readMethodMap = new HashMap<String, Method>();
513 
514 		for (Iterator<PropertyDescriptor> iterator = asList.iterator(); iterator.hasNext();) {
515 			PropertyDescriptor propertyDescriptor = (PropertyDescriptor) iterator.next();
516 			String name = propertyDescriptor.getName();
517 
518 			//priCheckParams 这个属性里含有response
519 			if (name.equals("priCheckParams")) {
520 				continue;
521 			}
522 
523 			Method readMethod = propertyDescriptor.getReadMethod();
524 			if (readMethod != null) {
525 				readMethodMap.put(name, readMethod);
526 			}
527 		}
528 
529 		Object value;
530 		for (Class<?> clazz = action.getClass(); clazz != ActionSupport.class; clazz = clazz.getSuperclass()) {
531 
532 			Field[] declaredFields = clazz.getDeclaredFields();
533 			for (int i = 0; i < declaredFields.length; i++) {
534 				String name = declaredFields[i].getName();
535 				Method readMethod = readMethodMap.get(name);
536 				if (readMethod == null)
537 					continue;
538 				try {
539 					value = readMethod.invoke(action, new Object[] {});
540 
541 					if (name.equals("model")) {
542 						name = "_M";
543 					}
544 
545 					//空值和service类忽略
546 					if (value != null && !(value instanceof IBaseService)) {
547 						actionPropertiesValues.put(name, value);
548 						if (needToDealAsObject(value.getClass()) && !isVelocityFill) {
549 							//java.lang、java.util等基本类型
550 							parseGetterOfObject(value, actionPropertiesValues, name + ".");
551 						}
552 					}
553 
554 				} catch (Exception e) {
555 				}
556 			}
557 
558 		}
559 
560 		return actionPropertiesValues;
561 	}
562 
563 	private Map<String, Object> getEnumWrappers(List<Class<?>> classes) {
564 		Map<String, Object> wrappers = new HashMap<String, Object>();
565 		for (Class<?> domainClass : classes) {
566 			if (domainClass != null) {
567 				List<Class<?>> clazzes;
568 				if (enumsInClass.containsKey(domainClass)) {
569 					clazzes = enumsInClass.get(domainClass);
570 				} else {
571 					clazzes = EnumTypeUtils.getEnumClassInDomain(domainClass);
572 					enumsInClass.put(domainClass, clazzes);
573 				}
574 				EnumTypeWrapper wrapper;
575 				for (Class<?> enumClass : clazzes) {
576 					//名称支持两种方式:类名称和带包名全路径(使用'-'替代'.')
577 					wrapper = new EnumTypeWrapper(enumClass);
578 					wrappers.put(enumClass.getName().replaceAll("\\.", "-"), wrapper);
579 					wrappers.put(ClassHelper.getNameWithoutPackage(enumClass), wrapper);
580 				}
581 			}
582 		}
583 		return wrappers;
584 	}
585 
586 	private boolean needToDealAsObject(Class<?> clazz) {
587 		Package pack = clazz.getPackage();
588 		return !(clazz.isPrimitive() || (pack != null && pack.getName().startsWith("java.lang"))
589 				|| (pack != null && pack.getName().startsWith("java.util")) || (pack != null && pack.getName().startsWith("java.math")) || (pack != null && pack
590 				.getName().startsWith("java.sql")));
591 	}
592 
593 	private void parseGetterOfObject(Object obj, Map<String, Object> models, String prefix) {
594 		Method[] ms = obj.getClass().getMethods();
595 		String name;
596 		Object attObj;
597 		for (Method m : ms) {
598 			if (m.getName().startsWith("get") && m.getName().length() > 3) {
599 				name = String.valueOf(m.getName().charAt(3)).toLowerCase() + m.getName().substring(4);
600 				try {
601 					if (ReflectionUtils.findField(obj.getClass(), name) != null) {
602 						attObj = m.invoke(obj, new Object[] {});
603 						if (attObj != null) {
604 							//date
605 							if (attObj instanceof java.util.Date && m.isAnnotationPresent(DateFormat.class)) {
606 								DateFormat pattern = m.getAnnotation(DateFormat.class);
607 								SimpleDateFormat format = new SimpleDateFormat(pattern.value());
608 								models.put(prefix + name, format.format(attObj));
609 							} else if (m.isAnnotationPresent(Enumerated.class)) {
610 								Enumerated enumAnno = m.getAnnotation(Enumerated.class);
611 								if (enumAnno.value() == javax.persistence.EnumType.STRING) {
612 									models.put(prefix + name, ((Enum<?>) attObj).name());
613 								} else if (enumAnno.value() == javax.persistence.EnumType.ORDINAL) {
614 									models.put(prefix + name, ((Enum<?>) attObj).ordinal());
615 								}
616 							} else {
617 								if (!needToDealAsObject(attObj.getClass())) {
618 									models.put(prefix + name, attObj);
619 								} else {
620 									parseGetterOfObject(attObj, models, prefix + name + ".");
621 								}
622 							}
623 						}
624 					}
625 				} catch (SecurityException e) {
626 					e.printStackTrace();
627 				} catch (IllegalArgumentException e) {
628 					e.printStackTrace();
629 				} catch (IllegalAccessException e) {
630 					e.printStackTrace();
631 				} catch (InvocationTargetException e) {
632 					e.printStackTrace();
633 				}
634 			}
635 		}
636 	}
637 
638 	private List<Opera> getOperationByPriviledge(List<Opera> operas, BaseActionSupport action) {
639 		Iterator<Opera> it = operas.iterator();
640 		List<Opera> operList = new LinkedList<Opera>();
641 		Bundle bd = GBoatClassLoader.getInstance().getBundle(action.getClass().getPackage().getName());
642 		Opera opera;
643 		while (it.hasNext()) {
644 			opera = it.next();
645 			String operCode = opera.getCode();
646 			if (!StringUtils.isEmpty(operCode)) {
647                 Map<Object, Object> params = action.getPriCheckParams();
648 				params.put("ACTION_NAME", action.getClass().getName());
649 				params.put("METHOD_NAME", StringUtils.defaultIfBlank(opera.getInvokeMethod(), opera.getCode()));
650 				params.put("REQUEST", action.request);
651 				boolean priCheckResult = PrivilegeCheckServiceFactory.operationCheckServiceByMethodName(params, bd);
652 				//只有权限允许添加该操作
653 				if (priCheckResult) {
654 					operList.add(opera);
655 				}
656 			}
657 		}
658 
659 		return operList;
660 	}
661 }