Java tutorial
//============================================================================== // file : $Id$ // project: corner // // last change: date: $Date$ // by: $Author$ // revision: $Revision$ //------------------------------------------------------------------------------ //copyright: Beijing Maxinfo Technology Ltd. http://www.bjmaxinfo.com //License: the Apache License, Version 2.0 (the "License") //============================================================================== package corner.service.tree; import java.util.List; import org.apache.tapestry.IPage; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import corner.model.tree.ITreeAdaptor; import corner.service.EntityService; import corner.util.BeanUtils; /** * ??tee??. * * TODO :? * * @author <a href="mailto:jun.tsai@bjmaxinfo.com">Jun Tsai</a> * @author <a href="mailto:xf@bjmaxinfo.com">xiafei</a> * @author <a href="mailto:Ghostbb@bjmaxinfo.com">Ghostbb</a> * @version $Revision$ * @since 2.5 */ public class TreeService extends EntityService { //? private static final String COUNT_ALL_NODE_HSQL = "select count(*) from %s"; // private static final String DELETE_NODE_HSQL = "delete %s n where (n.left between ? and ? )"; // private static final String UPDATE_LEFT_HSQL = "update %s n set n.left=n.left+%d where n.left>?"; //? private static final String UPDATE_RIGHT_HSQL = "update %s n set n.right=n.right+%d where n.right>?"; /** * * @param page * * @param clazz class * @param depend * @param depth ? */ public List getDepthTree(IPage page, Class clazz, String[] depends, int depth, int left, int right) { DetachedCriteria criteria = DetachedCriteria.forClass(clazz); if (depth == 1) { // select * from MP_S_ACCOUNT_ITEM_CODE where tree_depth = 1; criteria.add(Restrictions.eq(ITreeAdaptor.DEPTH_PRO_NAME, depth)); } else { // select * from MP_S_ACCOUNT_ITEM_CODE where tree_depth = 2 and tree_left_code > 1 and tree_right_code < 8; Criterion leftright = Restrictions.and(Restrictions.gt(ITreeAdaptor.LEFT_PRO_NAME, left), Restrictions.lt(ITreeAdaptor.RIGHT_PRO_NAME, right)); criteria.add(Restrictions.and(Restrictions.eq(ITreeAdaptor.DEPTH_PRO_NAME, depth), leftright)); } // if (page instanceof ITreeQueryPage) { ((ITreeQueryPage) page).appendCriteria(criteria, depends); } criteria.addOrder(Order.asc(ITreeAdaptor.LEFT_PRO_NAME)); return findByCriteria(criteria); } /** * * @param page * @param queryClassName className * @param depend * @param depth ? */ @SuppressWarnings("unchecked") public List getDepthTree(IPage page, String queryClassName, String[] depends, int depth, int left, int right) { Class clazz; try { clazz = Class.forName(queryClassName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } return getDepthTree(page, clazz, depends, depth, left, right); } /** * ?.? * <p>????? * * @param node * ? * @param parentNode * @param clazz ?,. */ public void saveTreeChildNode(ITreeAdaptor node, ITreeAdaptor parentNode, Class clazz) { String treeClassName = getTreeClassName(node, clazz); if (parentNode == null) { // ? parentNode = (ITreeAdaptor) BeanUtils.instantiateClass(EntityService.getEntityClass(node).getName()); parentNode.setLeft(0); parentNode.setDepth(0); long rowCount = (Long) find(String.format(COUNT_ALL_NODE_HSQL, treeClassName)).get(0); parentNode.setRight((int) (rowCount * 2 + 1)); } else { // reload parent object refresh(parentNode); } // ? int parentRight = parentNode.getRight(); // /* * update table set left=left+2 where left>parentRight * update table set right=right+2 where right>=parentRight */ String updateLeftHQL = String.format(UPDATE_LEFT_HSQL, treeClassName, 2); bulkUpdate(updateLeftHQL, new Object[] { parentRight }); String updateRightHQL = String.format(UPDATE_RIGHT_HSQL, treeClassName, 2); bulkUpdate(updateRightHQL, new Object[] { parentRight - 1 }); // ? node.setLeft(parentRight); node.setRight(parentRight + 1); node.setDepth(parentNode.getDepth() + 1); // ?? saveOrUpdate(node); if (parentNode.getId() != null) { refresh(parentNode); } } /** * * * @param clazz * */ @SuppressWarnings("unchecked") public List<? extends ITreeAdaptor> getTree(Class<? extends ITreeAdaptor> clazz) { DetachedCriteria criteria = DetachedCriteria.forClass(clazz); criteria.addOrder(Order.asc(ITreeAdaptor.LEFT_PRO_NAME)); return findByCriteria(criteria); } /** * ?. * <p> * n>0? * n<0?. * * @param node * * @param n ? * @param clazz */ public void moveNode(ITreeAdaptor node, int n, Class clazz) { if (n == 0) { return; } IMoveTreeNodeProcessor processor = createSubProcessor(node, this, n); processor.execute(node, this, n, clazz); } private IMoveTreeNodeProcessor createSubProcessor(ITreeAdaptor node, EntityService service, int n) { if (n > 0) { return new MoveUpProcessor(); } else { return new MoveDownProcessor(); } } private String getTreeClassName(ITreeAdaptor node, Class clazz) { if (clazz != null) { return clazz.getName(); } else { return EntityService.getEntityClass(node).getName(); } } /** * * * @param node * @param clazz ?. */ public void deleteTreeNode(ITreeAdaptor node, Class clazz) { String treeClassName = getTreeClassName(node, clazz); int left = node.getLeft(); int right = node.getRight(); int width = left - right - 1; // ?? bulkUpdate(String.format(DELETE_NODE_HSQL, treeClassName), new Object[] { left, right }); // ? bulkUpdate(String.format(UPDATE_LEFT_HSQL, treeClassName, width), new Object[] { right }); bulkUpdate(String.format(UPDATE_RIGHT_HSQL, treeClassName, width), new Object[] { right }); } }