View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2012-3-2 下午08:47:53
4    */
5   package gboat2.web.business.impl;
6   
7   import gboat2.base.core.dao.Page;
8   import gboat2.base.core.dao.PageBean;
9   import gboat2.base.core.dao.QuerySupport;
10  import gboat2.base.core.model.Module;
11  import gboat2.base.core.service.BaseService;
12  import gboat2.base.core.service.IModuleService;
13  import gboat2.web.business.IResourceBusiness;
14  import gboat2.web.model.Resource;
15  
16  import java.lang.reflect.InvocationTargetException;
17  import java.util.ArrayList;
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  
22  import org.apache.commons.lang3.StringUtils;
23  import org.springframework.beans.factory.annotation.Autowired;
24  import org.springframework.stereotype.Service;
25  import org.springframework.transaction.annotation.Transactional;
26  
27  /**
28   * 
29   * @author tanxw
30   * @since jdk1.6
31   * @date 2012-3-2
32   *  
33   */
34  @Transactional
35  @Service
36  public class ResourceBusinessImpl extends BaseService implements IResourceBusiness {
37  	
38  	@Autowired
39  	private IModuleService moduleService;
40  	
41  	/**
42  	 * 移动节点
43  	 * @param movedId	被移动的节点
44  	 * @param targetParentId	新的父节点
45  	 * @param targetIndex	如果是排序,被插入的节点
46  	 * @return true/false
47  	 */
48  	public boolean moveResource(String movedId, String targetParentId, int targetIndex) {
49  		if (StringUtils.isEmpty(movedId) || StringUtils.isEmpty(targetParentId)) {
50  			return false;
51  		}
52  		
53  		Resource moved = (Resource) get(Resource.class, movedId);
54  		moved.setParentId(targetParentId);
55  		double dispOrder = this.computeMovedResNewDispOrder(moved, targetParentId, targetIndex);
56  		moved.setDispOrder(dispOrder);
57  		
58  		return this.update(moved);
59  	}
60  	
61  	@Override
62  	public boolean deleteResource(Resource resource) {
63  		baseDAO.delete(resource);
64  		
65  		//删除所有与其关联的表
66  		Map<String, Object> params = new HashMap<String, Object>();
67  		params.put("resId", resource.getResId());
68  		baseDAO.deleteByQuery("delete from Authority where resId=:resId", params);
69  		baseDAO.deleteByQuery("delete from Operation where resId=:resId", params);
70  		baseDAO.deleteByQuery("delete from Shortcut where resId=:resId", params);
71  		baseDAO.deleteByQuery("delete from DataLevelAuthority where resId=:resId", params);
72  		
73  		//删除模块后,其子模块的父节点调整为删除节点的父节点;
74  		String parentId = resource.getParentId();
75  		double maxDispOder = this.getMaxOrderWithParent(parentId);
76  		List<Resource> children = getChildrenByParentId(resource.getResId());
77  		if (null != children) {
78  			for (Resource child : children) {
79  				child.setParentId(parentId);
80  				maxDispOder += 1;
81  				child.setDispOrder(maxDispOder);
82  				this.update(child);
83  			}
84  		}
85  		
86  		return true;
87  	}
88  	
89  	/**
90  	 * 计算被移动的节点的新排序值
91  	 * @param targetParentId 被移动的节点
92  	 * @param targetIndex 新节点在其父节点下的目标排序索引值
93  	 * @return 计算出的新的序号
94  	 */
95  	private double computeMovedResNewDispOrder(Resource moved, String targetParentId, int targetIndex) {
96  		List<Resource> children = this.getChildrenByParentId(targetParentId, moved.getSystemId());
97  		if (children.size() == 0) { //无子节点,则新添加的节点作为第一个子节点
98  			return 100f;
99  		}
100 		
101 		if (0 >= targetIndex) { //排在第一个
102 			return children.get(0).getDispOrder() / 2;
103 		}
104 		
105 		if (children.size() < targetIndex + 1) { //排在最后一个
106 			return children.get(children.size() - 1).getDispOrder() + 1;
107 		}
108 		
109 		//排在中间的情况
110 		double preDispOrder = children.get(targetIndex - 1).getDispOrder();
111 		double nextDispOrder = children.get(targetIndex).getDispOrder();
112 		
113 		return (preDispOrder + nextDispOrder) / 2;
114 	}
115 	
116 	@Override
117 	public double getMaxOrderWithParent(String parentId) {
118 		if (StringUtils.isEmpty(parentId)) {
119 			parentId = "0";
120 		}
121 		float order = 0.0f;
122 		String[][] params = { { Resource.class.getName() }, { "_parentId", parentId }, { QuerySupport.PARAM_ORDERBY, "dispOrder desc" },
123 		        { QuerySupport.PARAM_PAGESIZE, "1" } };
124 		List<Resource> mods = (List<Resource>) this.baseDAO.getPage(params).getResult();
125 		if (mods.size() > 0) {
126 			order = (float) mods.get(0).getDispOrder();
127 		}
128 		return order;
129 	}
130 	
131 	public Resource getResourcesTree(String systemId) {
132 		Resource root = new Resource();
133 		root.setResName("root");
134 		root.setResId("0");
135 		root.setLeaf(false);
136 		List<Resource> tops = this.getTopLevelResources(systemId);
137 		if (tops != null) {
138 			for (Resource res : tops) {
139 				res.setChildren(this.getChildrenRecursively(res));
140 				res.setLeaf(this.isLeaf(res));
141 			}
142 		}
143 		root.setChildren(tops);
144 		return root;
145 	}
146 	
147 	private boolean isLeaf(Resource res) {
148 		if ("0".equals(res.getSingleton())) {//如果是非单例节点,则不能视为叶子节点
149 			return false;
150 		}
151 		return null == res.getChildren() || res.getChildren().size() == 0;
152 	}
153 	
154 	private List<Resource> getChildrenRecursively(Resource parent) {
155 		List<Resource> list = this.getChildrenByParentId(parent.getResId());
156 		if (null != list) {
157 			for (Resource res : list) {
158 				res.setChildren(this.getChildrenRecursively(res));
159 				res.setLeaf(this.isLeaf(res));
160 			}
161 		}
162 		return list;
163 	}
164 	
165 	public List<Resource> getChildrenByParentId(String parentId) {
166 		String[][] params = new String[][] { { Resource.class.getName() }, { "_parentId", parentId }, { QuerySupport.PARAM_ORDERBY, "dispOrder" } };
167 		return (List<Resource>) baseDAO.queryList(params);
168 	}
169 	
170 	public List<Resource> getChildrenByParentId(String parentId, String systemId) {
171 		String[][] params = new String[][] { { Resource.class.getName() }, { "_parentId", parentId }, { "_systemId", systemId },
172 		        { QuerySupport.PARAM_ORDERBY, "dispOrder" } };
173 		return (List<Resource>) baseDAO.queryList(params);
174 	}
175 	
176 	public List<Resource> getTopLevelResources(String systemId) {
177 		if (StringUtils.isEmpty(systemId)) { //系统id不存在时直接返回空
178 			return null;
179 		}
180 		String[][] params = new String[][] { { Resource.class.getName() }, { "_parentId", "0" }, { "_systemId", systemId },
181 		        { QuerySupport.PARAM_ORDERBY, "dispOrder" } };
182 		return (List<Resource>) baseDAO.queryList(params);
183 	}
184 	
185 	public Resource getPreviousSibling(Resource res) {
186 		Resource brother = null;
187 		Map<String, Object> params = new HashMap<String, Object>();
188 		params.put(QuerySupport.PARAM_TABLENAME, Resource.class);
189 		params.put(QuerySupport.PARAM_PAGESIZE, "1");
190 		params.put(QuerySupport.PARAM_ORDERBY, "dispOrder desc");
191 		params.put("_parentId", res.getParentId());
192 		params.put("_dispOrder_lt", res.getDispOrder());
193 		List<Resource> mods = (List<Resource>) baseDAO.getPage(params).getResult();
194 		if (mods.size() > 0) {
195 			brother = mods.get(0);
196 		}
197 		return brother;
198 	}
199 	
200 	@Override
201 	public Page<Resource> getAnnotatedResources(String queryString, String page, String pagesize) {
202 		List<Module> modules;
203 		int currentPage = StringUtils.isEmpty(page) ? 1 : Integer.parseInt(page.trim());
204 		int size = StringUtils.isEmpty(pagesize) ? QuerySupport.PAGESIZE_DEFAULT : Integer.parseInt(pagesize.trim());
205 		
206 		if (StringUtils.isEmpty(queryString)) {
207 			modules = moduleService.getModules();
208 		} else {
209 			modules = moduleService.getModules(queryString);
210 		}
211 		
212 		//分页信息
213 		PageBean pageBean = new PageBean();
214 		pageBean.setCount(modules.size());
215 		pageBean.setPage(currentPage);
216 		pageBean.setPageSize(size);
217 		
218 		int fromIndex = (currentPage - 1) * size;
219 		int toIndex = fromIndex + size;
220 		toIndex = modules.size() < toIndex ? modules.size() : fromIndex + size; //防止边界溢出
221 		modules = modules.subList(fromIndex, toIndex); //根据分页截取
222 		
223 		List<Resource> results = new ArrayList<Resource>();
224 		//转换适配
225 		for (Module module : modules) {
226 			Resource res = new Resource();
227 			res.setResName(module.getModuleName());
228 			res.setModuleName(module.getModuleName());
229 			res.setResUrl(module.getEntryUri());
230 			res.setBundle(module.getBundleName());
231 			res.setActionClass(module.getClassName());
232 			res.setResCode(getAvailbleResCode(module));
233 			results.add(res);
234 		}
235 		
236 		return new Page<Resource>(results, pageBean);
237 	}
238 	
239 	private String getAvailbleResCode(Module module) {
240 		String code = module.getCode();
241 		if (StringUtils.isEmpty(code)) {
242 			code = module.getClassName();
243 			int n = code.lastIndexOf('.');
244 			if (n > 0) {
245 				code = code.substring(n + 1);
246 			}
247 			if (code.endsWith("Action")) {
248 				code = code.substring(0, code.length() - 6);
249 			}
250 		}
251 		
252 		int i = 1;
253 		String tryCode = code;
254 		while (getResourceByCode(tryCode) != null) {
255 			tryCode = code + i;
256 			i++;
257 		}
258 		return tryCode;
259 	}
260 	
261 	@Override
262 	public List<Resource> getAllResource() {
263 		String[][] params = new String[][] { { Resource.class.getName() } };
264 		List<Resource> list = (List<Resource>) super.query(params);
265 		return list;
266 	}
267 	
268 	@Override
269 	public Resource getResourceByResname(String resName) {
270 		Resource ret = null;
271 		String[][] params = { { Resource.class.getName() }, { "_resName", resName } };
272 		List<Resource> list = (List<Resource>) super.query(params);
273 		if (null != list && list.size() > 0) {
274 			ret = list.get(0);
275 		}
276 		return ret;
277 	}
278 	
279 	@Override
280 	public List<Resource> getResourceByUrl(String resUrl){
281 		String[][] params = {
282 				{Resource.class.getName()},
283 				{"_resUrl", resUrl}
284 		};
285 		return (List<Resource>)super.query(params);
286 	}
287 	
288 	@Override
289 	public Resource getResourceByCode(String resCode) {
290 		Map<String, Object> params = new HashMap<String, Object>();
291 		params.put(QuerySupport.PARAM_TABLENAME, Resource.class);
292 		params.put("_resCode", resCode);
293 		List<Resource> resourceList = (List<Resource>) baseDAO.queryList(params);
294 		if (resourceList.size() > 0) {
295 			return resourceList.get(0);
296 		}
297 		return null;
298 	}
299 	
300 	private Resource cloneResource(Resource res) {
301 		Resource newRes = new Resource();
302 		newRes.setResId(null);
303 		newRes.setActionClass(res.getActionClass());
304 		newRes.setBundle(res.getBundle());
305 		newRes.setDispOrder(res.getDispOrder());
306 		newRes.setLeaf(res.getLeaf());
307 		newRes.setModuleName(res.getModuleName());
308 		newRes.setResName(res.getResName());
309 		newRes.setResUrl(res.getResUrl());
310 		newRes.setSingleton(res.getSingleton());
311 		newRes.setStatus(res.getStatus());
312 		newRes.setSystemId(res.getSystemId());
313 		newRes.setType(res.getType());
314 		newRes.setResCode(res.getResCode() + 1);
315 		return newRes;
316 	}
317 	
318 	@Override
319 	public boolean copyResource(String copyedId, String targetParentId) {
320 		if (StringUtils.isEmpty(copyedId) || StringUtils.isEmpty(targetParentId)) {
321 			return false;
322 		}
323 		
324 		Resource copyed = (Resource) get(Resource.class, copyedId);
325 		List<Resource> children = getChildrenRecursively(copyed);
326 		
327 		//复制最顶层的节点
328 		Resource root = cloneResource(copyed);
329 		double order = getMaxOrderWithParent(targetParentId) + 1;
330 		root.setDispOrder(order);
331 		root.setParentId(targetParentId);
332 		save(root);
333 		
334 		//递归复制子节点
335 		if (null != children) {
336 			for (Resource item : children) {
337 				cloneAndSaveResourceRecursively(item, root.getResId());
338 			}
339 		}
340 		
341 		return true;
342 	}
343 	
344 	/**
345 	 * @param target 复制的目标节点
346 	 * @param mountToParent 要挂载到的父节点
347 	 * @throws IllegalAccessException
348 	 * @throws InvocationTargetException
349 	 */
350 	private void cloneAndSaveResourceRecursively(Resource target, String mountToParent) {
351 		Resource newRoot = cloneResource(target);
352 		newRoot.setParentId(mountToParent);
353 		save(newRoot);
354 		
355 		List<Resource> children = target.getChildren();
356 		if (null != children) {
357 			for (Resource item : children) {
358 				cloneAndSaveResourceRecursively(item, newRoot.getResId());
359 			}
360 		}
361 	}
362 }