corner.service.tree.TreeService.java Source code

Java tutorial

Introduction

Here is the source code for corner.service.tree.TreeService.java

Source

//==============================================================================
// 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 });

    }
}