读书人

基于Java实现的多层目录结构

发布时间: 2009-03-05 09:39:15 作者: liuhuituzi

最近在做小需求的时候,需要用到目录树,特地写了一个基于java的实现。
  由于需求原因,目前只实现了读部分的功能——如何将平面节点build成树。动态新增,删除等功能尚未实现。
  目录结构概念:
  Node:目录节点,具备节点属性信息
  NodeStore:平面目录节点持久化接口,提供方法如下:
  public List<T> findByType(String type); -- 根据目录类型,获取该类型下所有的节点(平面节点)
  public void add(T node);--将增加节点持久化
  public void update(T node);--将修改节点持久化
  public void delete(T node);--删除节点
  public void move(T src, T target); --将移动节点持久化
  NodeStore是一个接口,可以基于DB实现,也可以基于XML实现,或则其他你需要的方式。
  Tree:目录树,主要职责:
  通过NodeStore load某一类型目录的所有平面节点,build成树;
  根据节点id号,查找相应的节点信息
  动态新增,修改,删除,移动节点,通过NodeStore将变化持久化;
  目录结构实现类图:(目前只实现了读方法)
  附上Node,Tree类的核心代码
  Node.java
  1 public class Node implements Serializable, Comparable<Node> {
  2
  3 private static final long serialVersionUID = 8085266615416399579L;
  4
  5 private Integer id; // id号
  6 private Integer parentId;// 父亲id号
  7 private String name;// 目录名
  8 private String description;// 目录描述
  9 private String type;// 目录类型
  10
  11 private Node parent;// 父亲
  12 private List<Node> children;// 儿子
  13
  14 /**
  15 * 添加子节点,并且建立与当前节点的父子关系
  16 *
  17 * @param child 儿子节点
  18 */
  19 public void addChild(Node child) {
  20 if (child == null) {
  21 return;
  22 }
  23 // 设置当前节点为child的父节点
  24 child.setParent(this);
  25 // 当前节点增加child为儿子节点
  26 if (getChildren() == null) {
  27 setChildren(new ArrayList<Node>());
  28 }
  29 getChildren().add(child);
  30 }
  31
  32 /**
  33 * 删除子节点,并且建立与当前节点的父子关系
  34 *
  35 * @param child 儿子节点
  36 */
  37 public void removeChild(Node child) {
  38 if (child == null) {
  39 return;
  40 }
  41 // 将child节点的父节点清空
  42 child.setParent(null);
  43 if (getChildren() == null) {
  44 return;
  45 }
  46 // 当前节点删除child这个儿子节点
  47 getChildren().remove(child);
  48 }
  49
  50 /**
  51 * 得到全路径
  52 *
  53 * @param sep 分隔符号
  54 * @return
  55 */

56 public String getPathName(String sep) {
  57 String pathName = getName();
  58 if (getParent() != null) {
  59 pathName = getParent().getPathName(sep) + sep + pathName;
  60 }
  61 return pathName;
  62 }
  63
  64 /**
  65 * 判断是否root节点
  66 *
  67 * @return
  68 */
  69 public boolean isRootNode() {
  70 return getParentId() == -1;
  71 }
  72
  73 /**
  74 * 判断是否是叶子节点
  75 *
  76 * @return
  77 */
  78 public boolean isEndNode() {
  79 return getChildren() == null || getChildren().isEmpty();
  80 }
  81
  82 /**
  83 * 对当前节点的儿子节点进行排序
  84 */
  85 public void sortChildren() {
  86 if (isEndNode()) {
  87 return;
  88 }
  89 Collections.sort(getChildren());
  90 }
  91
  92 /**
  93 * 对当前节点的所有儿子节点进行排序
  94 */
  95 public void sortAllChidren() {
  96 if (isEndNode()) {
  97 return;
  98 }
  99 List<Node> children = getChildren();
  100 Collections.sort(children);
  101 for (Node child : children) {
  102 child.sortAllChidren();
  103 }
  104 }
  105
  106 /**
  107 * 将虚拟目录转换成JSONObject对象


  108 * <p>
  109 * 本身转换包含id、name两个属性,子节点转换为children属性的数组
  110 * </p>
  111 *
  112 * @return
  113 */
  114 public JSONObject toJson() {
  115 JSONObject jsonObject = new JSONObject();
  116 try {
  117 jsonObject.put("id", id);
  118 jsonObject.put("name", name);
  119 if (!isEndNode()) {
  120 JSONArray jsonArray = new JSONArray();
  121 for (Node child : getChildren()) {
  122 jsonArray.put(child.toJson());
  123 }
  124 jsonObject.put("children", jsonArray);
  125 }
  126 } catch (JSONException e) {
  127 // ignore
  128 }
  129 return jsonObject;
  130 }

131
  132 @Override
  133 public int compareTo(Node o) {
  134 return this.getId().compareTo(o.getId());
  135 }
  136
  137 }
  Tree.java:
  1 public class Tree<T extends Node> {
  2
  3 private String type;
  4 private Node root; // root节点
  5 private Map<Integer, T> nodeHolder = new HashMap<Integer, T>();// 节点持有器
  6
  7 private NodeStore<T> nodeStore;
  8
  9 /**
  10 * 将平面的node list构建成树
  11 *
  12 * @throws TreeException
  13 */
  14 public void build() throws TreeException {
  15 List<T> nodes = nodeStore.findByType(type);
  16 // 如果nodes为空,则不做任何处理
  17 if (nodes == null || nodes.isEmpty()) {
  18 return;
  19 }
  20 // 设置root和node持有器
  21 for (T node : nodes) {
  22 if (node.isRootNode()) {
  23 this.root = node;
  24 }
  25 nodeHolder.put(node.getId(), node);
  26 }
  27
  28 // 如果root为空,则build失败了
  29 if (root == null) {
  30 throw new TreeException("no root node found.");
  31 }
  32
  33 // 建立节点之前关系
  34 for (T node : nodes) {
  35 if (node.isRootNode()) {
  36 continue;
  37 }
  38 Node parent = getNodeById(node.getParentId());
  39 if (parent == null) {
  40 throw new TreeException("no parent node found.current node id is:" + node.getId());
  41 }
  42 parent.addChild(node);
  43 }
  44
  45 // 排序
  46 root.sortAllChidren();
  47 }
  48
  49 /**
  50 * 得到root节点
  51 *
  52 * @return
  53 */
  54 public Node getRoot() {
  55 return root;
  56 }
  57
  58 /**
  59 * 根据id得到对应节点
  60 *
  61 * @param id
  62 * @return
  63 */
  64 public Node getNodeById(Integer id) {
  65 return nodeHolder.get(id);
  66 }
  67
  68 public void setType(String type) {
  69 this.type = type;
  70 }
  71
  72 public void setNodeStore(NodeStore nodeStore) {
  73 this.nodeStore = nodeStore;
  74 }
  75
  76 }

3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/

读书人网 >JAVA认证

热点推荐