View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2012-5-21 下午04:51:39
4    */
5   package gboat2.attachment;
6   
7   import gboat2.base.core.util.JsonConfigUtil;
8   import gboat2.base.core.util.SpringContextUtil;
9   import gboat2.attachment.model.AttachConfig;
10  import gboat2.attachment.model.Attachment;
11  import gboat2.attachment.model.AttachmentVO;
12  import gboat2.attachment.model.DownloadRecord;
13  import gboat2.attachment.model.TypedAttachments;
14  import gboat2.attachment.service.IAttachmentService;
15  import gboat2.attachment.util.ConfigUtil;
16  
17  import java.io.File;
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.LinkedHashMap;
21  import java.util.List;
22  import java.util.Map;
23  
24  import net.sf.json.JSONArray;
25  import net.sf.json.JSONObject;
26  
27  import org.apache.commons.beanutils.BeanUtils;
28  import org.apache.commons.collections.CollectionUtils;
29  import org.apache.commons.lang3.StringUtils;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * 
35   * 将初始预期应该上传的文件与已经上传的附件做对比合并,形成前端附件上传组件所需要的附件列表
36   * @author tanxw
37   * @since jdk1.6
38   * @date 2012-5-21
39   *  
40   */
41  
42  public class AttachmentHelper {
43  	
44  	private static final Logger logger = LoggerFactory.getLogger(AttachmentHelper.class);
45  	
46  	private static final byte CONFIG_ID_FIELD = 0;
47  	
48  	private static final byte NAME_FIELD = 1;
49  	
50  	private static final byte REQUIRED_FIELD = 2;
51  	
52  	private static final byte MAX_FILE_COUNT_FIELD = 3;
53  	
54  	private static final byte FILTERS_FIELD = 4;
55  	
56  	protected AttachmentHelper() {
57  	}
58  	
59  	/**
60  	 * 根据belongId返回某个宿主对象的附件列表
61  	 * @param belongId 宿主id
62  	 * @return  返回某个对象的附件列表
63  	 */
64  	public static List<Attachment> findAttachsBy(String belongId) {
65  		IAttachmentService uploadService = getAttachmentService();
66  		if (StringUtils.isNotEmpty(belongId)) {
67  			return uploadService.getAttachmentsByBelongId(belongId);
68  		} else {
69  			return null;
70  		}
71  	}
72  	
73  	/**
74  	 * 根据belongId返回某个宿主对象的附件列表
75  	 * @param belongId 宿主id
76  	 * @return  返回某个对象的附件列表
77  	 */
78  	public static List<AttachmentVO> findAttachVOsBy(String belongId) {
79  		IAttachmentService uploadService = getAttachmentService();
80  		if (StringUtils.isNotEmpty(belongId)) {
81  			return uploadService.getAttachmentVOsByBelongId(belongId);
82  		} else {
83  			return null;
84  		}
85  	}
86  	
87  	/**
88  	 * 返回附件对应的文件对象
89  	 * @param attach
90  	 * @return real file
91  	 */
92  	public static File getAttachmentFile(Attachment attach) {
93  		if (null == attach) {
94  			return null;
95  		}
96  		return new File(ConfigUtil.getSavepathRoot() + attach.getSavePath());
97  	}
98  
99      public static List<Attachment> getAttachmentsByAttachIds(String attachIds) {
100         IAttachmentService uploadService = getAttachmentService();
101         return uploadService.getAttachmentsByAttachIds(attachIds);
102     }   
103     
104 	/**
105 	 * 根据belongId, attachType返回某个宿主对象的附件列表
106 	 * @param belongId 宿主id
107 	 * @param attachType 附件类型
108 	 * @return  返回某个对象的附件列表
109 	 * @deprecated replaced by {@link IAttachmentService#getAttachmentsBy(String, String)}
110 	 */
111 	public static List<Attachment> findAttachsBy(String belongId, String attachType) {
112 		IAttachmentService uploadService = getAttachmentService();
113 		if (StringUtils.isNotEmpty(belongId) || StringUtils.isNotEmpty(attachType)) {
114 			return uploadService.getAttachmentsBy(belongId, attachType);
115 		} else {
116 			return null;
117 		}
118 	}
119 	
120 	/**
121 	 * 根据belongId, attachType返回某个宿主对象的附件列表
122 	 * @param belongId 宿主id
123 	 * @param attachNames 附件类型
124 	 * @return  返回某个对象的附件列表
125      * @deprecated replaced by {@link IAttachmentService#getAttachmentsBy(String, String[])}
126 	 */
127 	public static List<Attachment> findAttachsBy(String belongId, String[] attachNames) {
128 		IAttachmentService uploadService = getAttachmentService();
129 		if (StringUtils.isNotEmpty(belongId) && attachNames != null) {
130 			return uploadService.getAttachmentsBy(belongId, attachNames);
131 		}
132 		return null;
133 	}
134 	
135 	/**
136 	 * 根据指定的附件列表及belongId, 计算出某个宿主的经排序后的附件列表
137 	 * @param belongId 宿主id,如果belongId为null,则认为指定的附件列表中所有附件均未上传过
138 	 * @param types  要求的附件列表,如new String[][]{{"附件1", "0"},{"附件2", "1"},{"附件3", "1"}},1为必传附件,0为选传附件
139 	 * @return 排好序的附件列表
140 	 * @deprecated
141 	 */
142 	public static List<Attachment> findSortedAttachsBy(String belongId, String[][] types) {
143 		List<Attachment> attachs = new ArrayList<Attachment>();
144 		
145 		List<Attachment> uploadedAttachs = findAttachsBy(belongId);
146 		if (null == types) {
147 			logger.warn("can't sort attachments for types is null, please check!");
148 			return uploadedAttachs;
149 		}
150 		for (String[] type : types) {
151 			attachs.add(getAttachByType(type, uploadedAttachs));
152 		}
153 		return attachs;
154 	}
155 	
156 	//根据传入的附件类型,检查该附件是否已上传,如果已上传则返回该附件,否则返回一个新的空附件对象
157 	@Deprecated
158 	private static Attachment getAttachByType(String[] attachType, List<Attachment> uploadedAttachs) {
159 		Attachment attach = new Attachment();
160 		attach.setAttachName(attachType[NAME_FIELD]);
161 		attach.setRequired(attachType[REQUIRED_FIELD]);
162 		
163 		if (null == uploadedAttachs || uploadedAttachs.size() <= 0) {//如果还没有上传过附件
164 			return attach;
165 		}
166 		
167 		for (Attachment att : uploadedAttachs) { //该附件已经上传
168 			if (attachType[NAME_FIELD].equals(att.getAttachName())) {
169 				att.setRequired(attachType[REQUIRED_FIELD]);
170 				return att;
171 			}
172 		}
173 		
174 		return attach; //已经上传部分附件,但该附件还未上传
175 	}
176 	
177 	/**
178 	 * 根据指定的附件列表及belongId, 计算出某个宿主的经排序后的附件列表
179 	 * @param belongId 宿主id
180 	 * @param types  要求的附件列表,如new String[][]{{"附件1", "0"},{"附件2", "1"},{"附件3", "1"}},1为必传附件,0为选传附件
181 	 * @return 排后序的附件列表的json数组字符串表示形式,如果附件列表为空,则返回"[]".
182 	 * @deprecated
183 	 */
184 	public static String findSortedAttachsJsonBy(String belongId, String[][] types) {
185 		return findAttachsJsonBy(belongId, types);
186 	}
187 	
188 	/**
189 	 * 将某个belongId的所有附件与指定的附件类型进行组合,生成前端附件组件所需的json数据结构
190 	 * @param belongId 宿主id
191 	 * @param types  附件类型描述,如new String[][]{{"类型1", "0","memo"},...},1为必传附件,0为选传附件。如果只是查看附件,则本参数置为null即可。
192 	 * @return 返回符合前端附件上传组件配置项所需的json数据格式,其格式为:
193 	 * <pre>
194 	 {
195 		types : [{name:'类型1', required : 1...},...], 
196 		uploadeds : [] //附件列表的json格式
197 	 }
198 		</pre>
199 	 * @deprecated replaced by {@link #findAttachsJsonBy(String, List)}
200 	 */
201 	public static String findAttachsJsonBy(String belongId, String[][] types) {
202 		JSONObject root = new JSONObject();
203 		JSONArray uploadeds = new JSONArray();
204 		JSONArray typesArr = null;
205 		if (null != types) {
206 			typesArr = parseAttachTypes(types);
207 		}
208 		root.accumulate("types", typesArr);
209 		
210 		List<AttachmentVO> attachs = findAttachVOsBy(belongId);
211 		if (null != attachs) {
212 			uploadeds = JSONArray.fromObject(attachs, JsonConfigUtil.getJsonConfig());
213 		}
214 		root.accumulate("uploadeds", uploadeds);
215 		return root.toString().replace('"', '\'');
216 	}
217 	
218 	/**
219 	 * 获取某个模块的所有附件
220 	 * @param configCode 配置模块的编码
221 	 * @param belongId belongId 如果belongId为空,则不查询附件列表,适合在新增数据的情况下使用
222 	 * @return TypedAttachments
223 	 */
224 	public static TypedAttachments findAttachmentsBy(String configCode, String belongId) {
225 		TypedAttachments atts = new TypedAttachments();
226 		if (StringUtils.isNotEmpty(belongId)) {
227 			atts.setUploadeds(findAttachsBy(belongId));
228 		}
229 		
230 		if (StringUtils.isNotEmpty(configCode)) {//
231 			List<AttachConfig> oldlist = getAttachmentService().getAvailableAttachTypesByCode(configCode);
232 			if (null != oldlist) {//防止查出的结果修改后被自动持久化
233 				List<AttachConfig> newlist = new ArrayList<AttachConfig>(oldlist.size());
234 				for (AttachConfig attachConfig : oldlist) {
235 					AttachConfig newAttachConfig = new AttachConfig();
236 					try {
237 						BeanUtils.copyProperties(newAttachConfig, attachConfig);
238 					} catch (Exception e) {
239 						logger.error("copy AttachConfig error!", e);
240 						throw new RuntimeException("copy AttachConfig error!", e);
241 					}
242 					newlist.add(newAttachConfig);
243 				}
244 				atts.setTypes(newlist);
245 			}
246 		}
247 		return atts;
248 	}
249 	
250 	/**
251 	 * 根据业务模块的编码及主记录的主键,获取某个业务模块的所有附件配置对象及其对应的附件列表
252 	 * @param configCode 业务模块的编码
253 	 * @param belongId 业务记录的主键(主表的ID),可以为 <code>null</code>
254 	 * @return 对应业务模块下所有的附件配置对象及其对应的附件列表,如果没有符合条件的记录则返回一个长度为 0 的 map
255 	 */
256 	public static Map<AttachConfig, List<Attachment>> findAttachments(String configCode, String belongId) {
257 	    IAttachmentService uploadService = getAttachmentService();
258 	    List<AttachConfig> acList = uploadService.getAvailableAttachTypesByCode(configCode);
259 	    if(CollectionUtils.isEmpty(acList))
260 	        return new HashMap<AttachConfig, List<Attachment>>();
261 
262         List<Attachment> allAttachments = null;
263         if(StringUtils.isNotBlank(belongId)) {
264             allAttachments = uploadService.getAttachmentsByBelongId(belongId.trim());
265         }
266   
267 	    Map<AttachConfig, List<Attachment>> result = new LinkedHashMap<AttachConfig, List<Attachment>>(acList.size());
268 	    for (AttachConfig attachConfig : acList) {
269 	        List<Attachment> attachList = new ArrayList<Attachment>();
270 	        if(CollectionUtils.isNotEmpty(allAttachments)) {
271 	            for (Attachment att : allAttachments) {
272                     if(attachConfig.getConfigId().equals(att.getConfigId())) {
273                         attachList.add(att);
274                     }
275                 }
276 	        }
277 	        result.put(attachConfig, attachList);
278         }
279 	    return result;
280 	}
281 	
282 	/**
283 	 * 获取某个模块的所有附件
284 	 * @param configCode 配置模块的编码
285 	 * @param belongId belongId 如果belongId为空,则不查询附件列表,适合在新增数据的情况下使用
286 	 * @return json 字符串,格式如:
287 	 *   <pre>
288 		 {
289 			types : [{name:'类型1', required : 'true', ...},...], 
290 			uploadeds : [] //附件列表的json格式
291 		 }
292 		</pre>
293 	 * 
294 	 */
295 	public static String findAttachmentsJsonBy(String configCode, String belongId) {
296 		return toJsonString(findAttachmentsBy(configCode, belongId));
297 	}
298 	
299 	@Deprecated
300 	private static JSONArray parseAttachTypes(String[][] types) {
301 		JSONObject typeObj;
302 		JSONArray typesArr = new JSONArray();
303 		for (String[] type : types) {
304 			typeObj = new JSONObject();
305 			if (type.length > CONFIG_ID_FIELD) {
306 				typeObj.accumulate("configId", type[CONFIG_ID_FIELD]);
307 			}
308 			if (type.length > NAME_FIELD) {
309 				typeObj.accumulate("attachType", type[NAME_FIELD]);
310 			}
311 			if (type.length > REQUIRED_FIELD) {
312 				typeObj.accumulate("required", type[REQUIRED_FIELD]);
313 			}
314 			if (type.length > MAX_FILE_COUNT_FIELD) {
315 				typeObj.accumulate("maxFileCount", Integer.valueOf(type[MAX_FILE_COUNT_FIELD]));
316 			}
317 			if (type.length > FILTERS_FIELD) {
318 				typeObj.accumulate("fileFilters", type[FILTERS_FIELD]);
319 			}
320 			typesArr.add(typeObj);
321 		}
322 		
323 		return typesArr;
324 	}
325 	
326 	/**
327 	 * @deprecated replaced by {@link #toJsonString(TypedAttachments)}
328 	 * 转换为附件组件使用的json字符串
329 	 * @param attachs	附件列表
330 	 * @param types		附件类型描述
331 	 * @return
332 	 */
333 	public static String toAttachsJson(List<Attachment> attachs, String[][] types) {
334 		JSONObject root = new JSONObject();
335 		JSONArray typesArr = null;
336 		JSONArray uploadeds = new JSONArray();
337 		if (null != types) {
338 			typesArr = parseAttachTypes(types);
339 		}
340 		root.accumulate("types", typesArr);
341 		
342 		if (null != attachs) {
343 			uploadeds = JSONArray.fromObject(attachs, JsonConfigUtil.getJsonConfig());
344 		}
345 		root.accumulate("uploadeds", uploadeds);
346 		return root.toString().replace('"', '\'');
347 	}
348 	
349 	public static String toJsonString(TypedAttachments attachs) {
350 		return JSONObject.fromObject(attachs, JsonConfigUtil.getJsonConfig()).toString().replace('"', '\'');
351 	}
352 	
353 	/**
354 	 * @deprecated
355 	 * @param belongId
356 	 * @param types
357 	 * @return
358 	 */
359 	public static String findAttachsJsonByAttachNames(String belongId, String[][] types) {
360 		JSONObject root = new JSONObject();
361 		JSONArray typesArr = new JSONArray();
362 		JSONArray uploadeds = new JSONArray();
363 		String attachNames[] = new String[types.length];
364 		JSONObject typeObj = null;
365 		if (null != types) {
366 			int i = 0;
367 			for (String[] type : types) {
368 				typeObj = new JSONObject();
369 				if (type.length > 0) {
370 					typeObj.accumulate("typeId", type[CONFIG_ID_FIELD]);
371 				}
372 				
373 				if (type.length > 1) {
374 					typeObj.accumulate("name", type[NAME_FIELD]);
375 				}
376 				if (type.length > 2) {
377 					typeObj.accumulate("required", type[REQUIRED_FIELD]);
378 				}
379 				if (type.length > 3) {
380 					typeObj.accumulate("memo", type[MAX_FILE_COUNT_FIELD]);
381 				}
382 				
383 				typesArr.add(typeObj);
384 				
385 				attachNames[i++] = type[1];
386 			}
387 		}
388 		root.accumulate("types", typesArr);
389 		
390 		List<Attachment> attachs = findAttachsBy(belongId, attachNames);
391 		if (null != attachs) {
392 			uploadeds = JSONArray.fromObject(attachs, JsonConfigUtil.getJsonConfig());
393 		}
394 		root.accumulate("uploadeds", uploadeds);
395 		return root.toString().replace('"', '\'');
396 	}
397 	
398 	/**
399 	 * 将一个附件列表转成json 数组字符串形式
400 	 * @param attachs 附件列表
401 	 * @return 附件列表的json字符串,如果附件列表为空,则返回"[]".
402 	 */
403 	public static String toJsonString(List<Attachment> attachs) {
404 		String json = "[]";
405 		if (null != attachs) {
406 			json = JSONArray.fromObject(attachs, JsonConfigUtil.getJsonConfig()).toString().replace('"', '\'');
407 		}
408 		return json;
409 	}
410 	
411 	/**
412 	 * 根据指定belongId的附件列表, 返回json字符串形式
413 	 * @param belongId 宿主id
414 	 * @return findAttachsBy(belongId)的json字符串,如果附件列表为空,则返回"[]".
415 	 */
416 	public static String findAttachsJsonBy(String belongId) {
417 		return toJsonString(findAttachsBy(belongId));
418 	}
419 	
420 	/**
421 	 * 批量更新附件的belongId,将指定的所有附件的belongId更新为指定的值
422 	 * @param attachIds 附件id
423 	 * @param belongId 宿主id
424 	 */
425 	public static void updateAttachsBelongId(String[] attachIds, String belongId) {
426 		
427 		if (attachIds != null && attachIds.length > 0) {
428 			// 更新附件
429 			IAttachmentService uploadService = getAttachmentService();
430 			uploadService.updateAttachsBelongId(attachIds, belongId);
431 		}
432 	}
433 	
434 	private static IAttachmentService getAttachmentService() {
435 		return (IAttachmentService) SpringContextUtil.getInstance().getBeanOfId("attachmentServiceBean");
436 	}
437 	
438 	/**
439 	 * 保存附件
440 	 * @param Attachment attach 附件
441 	 */
442 	public static void saveAttachment(Attachment attach) {
443 		getAttachmentService().save(attach);
444 	}
445 	
446 	/**
447 	 * 删除附件(可以删除多个,id以,分隔)
448 	 * @param attachIds Attachment的id组成的字符串数组
449 	 */
450 	public static void deleteAttachments(String[] attachIds) {
451 		getAttachmentService().deleteAttachments(attachIds);
452 	}
453 	
454 	/**
455 	 * 判断指定类型的附件是否被下载过
456 	 * @param organId
457 	 * @param belongId
458 	 * @param attachType
459 	 */
460 	public static Boolean isDownLoadFile(String organId, String belongId, String attachType) {
461 		return getAttachmentService().isDownLoadFile(organId, belongId, attachType);
462 	}
463 	
464 	/**
465 	 * 判断指定类型的附件是否被下载过
466 	 * @param organId
467 	 * @param belongId
468 	 * @param attachType
469 	 */
470 	public static DownloadRecord getLastDownloadRecord(String organId, String belongId, String attachType) {
471 		return getAttachmentService().getLastDownloadRecord(organId, belongId, attachType);
472 	}
473 	
474 	/**
475 	 * 删除附件
476 	 * @param attachId Attachment id
477 	 */
478 	public static void deleteAttachment(String attachId) {
479 		getAttachmentService().deleteAttachment(attachId);
480 	}
481 	
482 	/**
483 	 * 删除 附件 by belongId
484 	 * @param belongId
485 	 * 		主对象的主键,同时又是附件的belongId
486 	 */
487 	public static void deleteAttachmentByBelongId(String belongId) {
488 		if (StringUtils.isEmpty(belongId)) {
489 			return;
490 		}
491 		getAttachmentService().deleteAttachmentByBelongId(belongId);
492 	}
493 	
494 	/**
495 	 * 取得保存附件的根路径,该路径是绝对路径,在读取附件文件时,需要将此根路径与savepath拼在一起
496 	 * @return path, it always end with "/", eg: "c:/files/".
497 	 */
498 	public static String getSavepathRoot() {
499 		return ConfigUtil.getSavepathRoot();
500 	}
501 	
502 	/**
503 	 * 获取指定附件的绝对路径,以便访问对应的文件
504 	 * @param attch
505 	 * @return
506 	 */
507 	public static String getAbsoluteSavepath(Attachment attch) {
508 		return ConfigUtil.getSavepathRoot() + attch.getSavePath();
509 	}
510 	
511 	/**
512 	 * @deprecated replaced by {@link IAttachmentService#getAvailableAttachTypesByCode(String)}
513 	 * @param attachCode
514 	 * @return
515 	 */
516 	public static String[][] getAvailableAttachTypeByCode(String attachCode) {
517 		return (String[][]) getAttachmentService().getAvailableAttachTypeByCode(attachCode);
518 	}
519 }