You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BitBucket插件实现仓库结构缩进格式化问题求助

BitBucket插件:修复仓库层级结构缩进展示问题

问题概述

开发BitBucket插件时,点击页面按钮通过Ajax调用Servlet获取仓库结构,期望输出带缩进的层级列表,但当前输出为无缩进的平级列表,无法正确展示文件夹与文件的层级关系。

期望效果

<ul>
<li>Folder 1
<ul>
<li>File 1</li>
<li>File 2</li>
</ul>
</li>
</ul>

当前错误输出

<ul>
<li>Folder 1</li>
<li>File 1</li>
<li>File 2</li>
</ul>

问题核心

自定义MyContentTreeCallback的onTreeNode方法中,错误地将拼接后的字符串路径存入列表(files.add(filePath)),而非直接使用BitBucket提供的ContentTreeNode对应的路径信息,导致后续Node类无法解析路径组件来构建层级结构。

解决方案(优先整合层级逻辑到Callback)

将树形结构的构建逻辑直接移入MyContentTreeCallback中,无需额外存储路径字符串,直接通过ContentTreeNode的路径组件实时构建层级,减少冗余处理。

修改后的代码

1. 自定义MyContentTreeCallback类

public class MyContentTreeCallback extends AbstractContentTreeCallback {
    private final Node root = new Node(null);
    private ContentTreeSummary fileSummary;

    @Override
    public void onEnd(@Nonnull ContentTreeSummary summary) {
        fileSummary = summary;
    }

    @Override
    public void onStart(@Nonnull ContentTreeContext context) {
        System.out.print("On start");
    }

    @Override
    public boolean onTreeNode(@Nonnull ContentTreeNode node) {
        // 直接使用节点的路径组件构建树形结构
        Node currentNode = root;
        for (String component : node.getPath().getComponents()) {
            currentNode = currentNode.children.computeIfAbsent(component, Node::new);
        }
        return true;
    }

    // 输出树形结构的方法
    public void writeTree(Appendable writer) throws IOException {
        root.writeTo(writer);
    }

    static final class Node {
        final String name;
        final Map<String, Node> children = new LinkedHashMap<>();

        Node(String name) {
            this.name = name;
        }

        void writeTo(Appendable w) throws IOException {
            if (name != null) {
                w.append("<li><a href='/'>").append(name).append("</a></li>\n");
            }
            if (!children.isEmpty()) {
                w.append("<ul>\n");
                for (Node ch : children.values()) {
                    ch.writeTo(w);
                }
                w.append("</ul>\n");
            }
        }
    }
}

2. 修改后的Servlet doGet方法

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    // 获取URL参数
    String projectName = req.getParameter("project");
    String repoName = req.getParameter("repository");

    Repository repo = repositoryService.getBySlug(projectName, repoName);

    MyContentTreeCallback callback = new MyContentTreeCallback();
    PageRequestImpl pr = new PageRequestImpl(0, 1000);

    // 遍历仓库目录,构建树形结构
    contentService.streamDirectory(repo, "Master", "", true, callback, pr);

    resp.setContentType("text/html");
    PrintWriter writer = resp.getWriter();
    writer.print("<html><body><p>Repository: " + repo.getName() + "</p>");
    
    // 直接输出构建好的树形结构
    callback.writeTree(writer);
    
    writer.print("</body></html>");
}

方案说明

  • 移除了原Callback中拼接路径字符串的冗余逻辑,直接通过ContentTreeNode的getPath().getComponents()获取路径分段,实时构建层级节点。
  • 将Node类内嵌到MyContentTreeCallback中,让树形结构的构建与回调逻辑紧密结合,避免对象类型不匹配的问题。
  • Servlet中无需再手动遍历列表添加节点,直接调用Callback的writeTree方法输出层级结构,简化流程。

内容的提问来源于stack exchange,提问作者MillieJA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:15:36