返回列表 上一筆 下一筆

📄 資料內容

import org.apache.axis.message.MessageElement;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;



import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import java.time.format.DateTimeParseException;

import java.util.*;



// 時間格式:和你現有 FORMATTER 一致

private static final DateTimeFormatter FORMATTER  = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

private static final DateTimeFormatter FMT_FALLBACK = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");



public List<TreeNodeBean> transformTree(String userType) throws Exception {

    // 1) 呼叫 WS,取回 XML 片段

    WsGetTreeSubdirResponseWsGetTreeSubdirResult result = service.wsGetTreeSubdir(userType);

    MessageElement[] anyArray = result.get_any();

    if (anyArray == null || anyArray.length == 0) {

        return List.of();

    }



    // 2) 直接把 MessageElement 當 DOM Element 使用

    Element root = anyArray[0];

    NodeList list = root.getElementsByTagName("TreeSubdir");



    // 3) 解析成 flat list(沿用你的 Builder)

    List<TreeNodeBean> flatList = new ArrayList<>(list.getLength());

    for (int i = 0; i < list.getLength(); i++) {

        Element e = (Element) list.item(i);



        String sftPath  = getChildText(e, "sft_path");

        String iftSid   = getChildText(e, "ift_sid");

        String sftName  = getChildText(e, "sft_name");

        String iKBCount = getChildText(e, "iKBCount");

        String dInit    = getChildText(e, "dinit_time");

        String dModi    = getChildText(e, "dmodi_time");

        String iftPrev  = getChildText(e, "ift_prev");



        TreeNodeBean child = new TreeNodeBean.Builder()

                .ftSid(iftSid)

                .ftName(sftName)

                .parent(iftPrev)

                .pathRaw(sftPath)

                .pathParts(splitPathSafe(sftPath))

                .kBCount(parseIntOrNull(iKBCount))                 // 比 Integer.valueOf 更安全

                .initTime(parseDateTimeSafely(dInit, FORMATTER))   // 允許空值/格式 fallback

                .modiTime(parseDateTimeSafely(dModi, FORMATTER))

                .build();



        flatList.add(child);

    }



    // 4) 建樹(只用 iftPrev)

    List<TreeNodeBean> roots = TreeUtils.buildTree(flatList);



    // 5) (可選)sft_path 檢核 + 紀錄異常

    Map<String, TreeNodeBean> idx = TreeUtils.buildIndex(flatList);

    for (TreeNodeBean n : flatList) {

        if (n.getFtPathRaw() != null && !n.getFtPathRaw().isBlank()) {

            boolean ok = TreeUtils.validateSftPath(n, idx);

            if (!ok) {

                LOGGER.warn("sft_path 檢核失敗 id={} raw={} actual={}",

                        n.getIftSid(),

                        n.getFtPathRaw(),

                        TreeUtils.getPathIdsFromRoot(n, idx, false));

            }

        }

    }



    // 6) 按你的慣例:回傳第一個 root 的 children(只有一個 root 的前提)

    return roots.isEmpty() ? List.of() : roots.get(0).getChildren();

}



/* ----------------- 工具函式 ----------------- */



private static String getChildText(Element parent, String tag) {

    NodeList nl = parent.getElementsByTagName(tag);

    if (nl == null || nl.getLength() == 0) return "";

    String s = nl.item(0).getTextContent();

    return s == null ? "" : s.trim();

}



private static List<String> splitPathSafe(String raw) {

    if (raw == null) return List.of();

    String s = raw.trim();

    if (s.startsWith("\\")) s = s.substring(1);

    if (s.endsWith("\\"))   s = s.substring(0, s.length() - 1);

    if (s.isEmpty()) return List.of();

    String[] parts = s.split("\\\\");

    List<String> out = new ArrayList<>(parts.length);

    for (String p : parts) if (p != null && !p.isBlank()) out.add(p.trim());

    return out;

}



private static Integer parseIntOrNull(String s) {

    if (s == null || s.isBlank()) return null;

    try { return Integer.parseInt(s.trim()); }

    catch (NumberFormatException e) { return null; }

}



private static LocalDateTime parseDateTimeSafely(String s, DateTimeFormatter primary) {

    if (s == null || s.isBlank()) return null;

    String v = s.trim();

    try { return LocalDateTime.parse(v, primary); }

    catch (DateTimeParseException e1) {

        try { return LocalDateTime.parse(v, FMT_FALLBACK); }

        catch (DateTimeParseException e2) { return null; }

    }

}

🔐 Base64 編碼內容

aW1wb3J0IG9yZy5hcGFjaGUuYXhpcy5tZXNzYWdlLk1lc3NhZ2VFbGVtZW50OwoKaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CgppbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CgoKCmltcG9ydCBqYXZhLnRpbWUuTG9jYWxEYXRlVGltZTsKCmltcG9ydCBqYXZhLnRpbWUuZm9ybWF0LkRhdGVUaW1lRm9ybWF0dGVyOwoKaW1wb3J0IGphdmEudGltZS5mb3JtYXQuRGF0ZVRpbWVQYXJzZUV4Y2VwdGlvbjsKCmltcG9ydCBqYXZhLnV0aWwuKjsKCgoKLy8g5pmC6ZaT5qC85byP77ya5ZKM5L2g54++5pyJIEZPUk1BVFRFUiDkuIDoh7QKCnByaXZhdGUgc3RhdGljIGZpbmFsIERhdGVUaW1lRm9ybWF0dGVyIEZPUk1BVFRFUiAgPSBEYXRlVGltZUZvcm1hdHRlci5vZlBhdHRlcm4oInl5eXkvTU0vZGQgSEg6bW06c3MiKTsKCnByaXZhdGUgc3RhdGljIGZpbmFsIERhdGVUaW1lRm9ybWF0dGVyIEZNVF9GQUxMQkFDSyA9IERhdGVUaW1lRm9ybWF0dGVyLm9mUGF0dGVybigieXl5eS1NTS1kZCBISDptbTpzcyIpOwoKCgpwdWJsaWMgTGlzdDxUcmVlTm9kZUJlYW4+IHRyYW5zZm9ybVRyZWUoU3RyaW5nIHVzZXJUeXBlKSB0aHJvd3MgRXhjZXB0aW9uIHsKCiAgICAvLyAxKSDlkbzlj6sgV1PvvIzlj5blm54gWE1MIOeJh+autQoKICAgIFdzR2V0VHJlZVN1YmRpclJlc3BvbnNlV3NHZXRUcmVlU3ViZGlyUmVzdWx0IHJlc3VsdCA9IHNlcnZpY2Uud3NHZXRUcmVlU3ViZGlyKHVzZXJUeXBlKTsKCiAgICBNZXNzYWdlRWxlbWVudFtdIGFueUFycmF5ID0gcmVzdWx0LmdldF9hbnkoKTsKCiAgICBpZiAoYW55QXJyYXkgPT0gbnVsbCB8fCBhbnlBcnJheS5sZW5ndGggPT0gMCkgewoKICAgICAgICByZXR1cm4gTGlzdC5vZigpOwoKICAgIH0KCgoKICAgIC8vIDIpIOebtOaOpeaKiiBNZXNzYWdlRWxlbWVudCDnlbYgRE9NIEVsZW1lbnQg5L2/55SoCgogICAgRWxlbWVudCByb290ID0gYW55QXJyYXlbMF07CgogICAgTm9kZUxpc3QgbGlzdCA9IHJvb3QuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRyZWVTdWJkaXIiKTsKCgoKICAgIC8vIDMpIOino+aekOaIkCBmbGF0IGxpc3TvvIjmsr/nlKjkvaDnmoQgQnVpbGRlcu+8iQoKICAgIExpc3Q8VHJlZU5vZGVCZWFuPiBmbGF0TGlzdCA9IG5ldyBBcnJheUxpc3Q8PihsaXN0LmdldExlbmd0aCgpKTsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3QuZ2V0TGVuZ3RoKCk7IGkrKykgewoKICAgICAgICBFbGVtZW50IGUgPSAoRWxlbWVudCkgbGlzdC5pdGVtKGkpOwoKCgogICAgICAgIFN0cmluZyBzZnRQYXRoICA9IGdldENoaWxkVGV4dChlLCAic2Z0X3BhdGgiKTsKCiAgICAgICAgU3RyaW5nIGlmdFNpZCAgID0gZ2V0Q2hpbGRUZXh0KGUsICJpZnRfc2lkIik7CgogICAgICAgIFN0cmluZyBzZnROYW1lICA9IGdldENoaWxkVGV4dChlLCAic2Z0X25hbWUiKTsKCiAgICAgICAgU3RyaW5nIGlLQkNvdW50ID0gZ2V0Q2hpbGRUZXh0KGUsICJpS0JDb3VudCIpOwoKICAgICAgICBTdHJpbmcgZEluaXQgICAgPSBnZXRDaGlsZFRleHQoZSwgImRpbml0X3RpbWUiKTsKCiAgICAgICAgU3RyaW5nIGRNb2RpICAgID0gZ2V0Q2hpbGRUZXh0KGUsICJkbW9kaV90aW1lIik7CgogICAgICAgIFN0cmluZyBpZnRQcmV2ICA9IGdldENoaWxkVGV4dChlLCAiaWZ0X3ByZXYiKTsKCgoKICAgICAgICBUcmVlTm9kZUJlYW4gY2hpbGQgPSBuZXcgVHJlZU5vZGVCZWFuLkJ1aWxkZXIoKQoKICAgICAgICAgICAgICAgIC5mdFNpZChpZnRTaWQpCgogICAgICAgICAgICAgICAgLmZ0TmFtZShzZnROYW1lKQoKICAgICAgICAgICAgICAgIC5wYXJlbnQoaWZ0UHJldikKCiAgICAgICAgICAgICAgICAucGF0aFJhdyhzZnRQYXRoKQoKICAgICAgICAgICAgICAgIC5wYXRoUGFydHMoc3BsaXRQYXRoU2FmZShzZnRQYXRoKSkKCiAgICAgICAgICAgICAgICAua0JDb3VudChwYXJzZUludE9yTnVsbChpS0JDb3VudCkpICAgICAgICAgICAgICAgICAvLyDmr5QgSW50ZWdlci52YWx1ZU9mIOabtOWuieWFqAoKICAgICAgICAgICAgICAgIC5pbml0VGltZShwYXJzZURhdGVUaW1lU2FmZWx5KGRJbml0LCBGT1JNQVRURVIpKSAgIC8vIOWFgeioseepuuWAvC/moLzlvI8gZmFsbGJhY2sKCiAgICAgICAgICAgICAgICAubW9kaVRpbWUocGFyc2VEYXRlVGltZVNhZmVseShkTW9kaSwgRk9STUFUVEVSKSkKCiAgICAgICAgICAgICAgICAuYnVpbGQoKTsKCgoKICAgICAgICBmbGF0TGlzdC5hZGQoY2hpbGQpOwoKICAgIH0KCgoKICAgIC8vIDQpIOW7uuaoue+8iOWPqueUqCBpZnRQcmV277yJCgogICAgTGlzdDxUcmVlTm9kZUJlYW4+IHJvb3RzID0gVHJlZVV0aWxzLmJ1aWxkVHJlZShmbGF0TGlzdCk7CgoKCiAgICAvLyA1KSDvvIjlj6/pgbjvvIlzZnRfcGF0aCDmqqLmoLggKyDntIDpjITnlbDluLgKCiAgICBNYXA8U3RyaW5nLCBUcmVlTm9kZUJlYW4+IGlkeCA9IFRyZWVVdGlscy5idWlsZEluZGV4KGZsYXRMaXN0KTsKCiAgICBmb3IgKFRyZWVOb2RlQmVhbiBuIDogZmxhdExpc3QpIHsKCiAgICAgICAgaWYgKG4uZ2V0RnRQYXRoUmF3KCkgIT0gbnVsbCAmJiAhbi5nZXRGdFBhdGhSYXcoKS5pc0JsYW5rKCkpIHsKCiAgICAgICAgICAgIGJvb2xlYW4gb2sgPSBUcmVlVXRpbHMudmFsaWRhdGVTZnRQYXRoKG4sIGlkeCk7CgogICAgICAgICAgICBpZiAoIW9rKSB7CgogICAgICAgICAgICAgICAgTE9HR0VSLndhcm4oInNmdF9wYXRoIOaqouaguOWkseaVlyBpZD17fSByYXc9e30gYWN0dWFsPXt9IiwKCiAgICAgICAgICAgICAgICAgICAgICAgIG4uZ2V0SWZ0U2lkKCksCgogICAgICAgICAgICAgICAgICAgICAgICBuLmdldEZ0UGF0aFJhdygpLAoKICAgICAgICAgICAgICAgICAgICAgICAgVHJlZVV0aWxzLmdldFBhdGhJZHNGcm9tUm9vdChuLCBpZHgsIGZhbHNlKSk7CgogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICB9CgoKCiAgICAvLyA2KSDmjInkvaDnmoTmhaPkvovvvJrlm57lgrPnrKzkuIDlgIsgcm9vdCDnmoQgY2hpbGRyZW7vvIjlj6rmnInkuIDlgIsgcm9vdCDnmoTliY3mj5DvvIkKCiAgICByZXR1cm4gcm9vdHMuaXNFbXB0eSgpID8gTGlzdC5vZigpIDogcm9vdHMuZ2V0KDApLmdldENoaWxkcmVuKCk7Cgp9CgoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tIOW3peWFt+WHveW8jyAtLS0tLS0tLS0tLS0tLS0tLSAqLwoKCgpwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0Q2hpbGRUZXh0KEVsZW1lbnQgcGFyZW50LCBTdHJpbmcgdGFnKSB7CgogICAgTm9kZUxpc3QgbmwgPSBwYXJlbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnKTsKCiAgICBpZiAobmwgPT0gbnVsbCB8fCBubC5nZXRMZW5ndGgoKSA9PSAwKSByZXR1cm4gIiI7CgogICAgU3RyaW5nIHMgPSBubC5pdGVtKDApLmdldFRleHRDb250ZW50KCk7CgogICAgcmV0dXJuIHMgPT0gbnVsbCA/ICIiIDogcy50cmltKCk7Cgp9CgoKCnByaXZhdGUgc3RhdGljIExpc3Q8U3RyaW5nPiBzcGxpdFBhdGhTYWZlKFN0cmluZyByYXcpIHsKCiAgICBpZiAocmF3ID09IG51bGwpIHJldHVybiBMaXN0Lm9mKCk7CgogICAgU3RyaW5nIHMgPSByYXcudHJpbSgpOwoKICAgIGlmIChzLnN0YXJ0c1dpdGgoIlxcIikpIHMgPSBzLnN1YnN0cmluZygxKTsKCiAgICBpZiAocy5lbmRzV2l0aCgiXFwiKSkgICBzID0gcy5zdWJzdHJpbmcoMCwgcy5sZW5ndGgoKSAtIDEpOwoKICAgIGlmIChzLmlzRW1wdHkoKSkgcmV0dXJuIExpc3Qub2YoKTsKCiAgICBTdHJpbmdbXSBwYXJ0cyA9IHMuc3BsaXQoIlxcXFwiKTsKCiAgICBMaXN0PFN0cmluZz4gb3V0ID0gbmV3IEFycmF5TGlzdDw+KHBhcnRzLmxlbmd0aCk7CgogICAgZm9yIChTdHJpbmcgcCA6IHBhcnRzKSBpZiAocCAhPSBudWxsICYmICFwLmlzQmxhbmsoKSkgb3V0LmFkZChwLnRyaW0oKSk7CgogICAgcmV0dXJuIG91dDsKCn0KCgoKcHJpdmF0ZSBzdGF0aWMgSW50ZWdlciBwYXJzZUludE9yTnVsbChTdHJpbmcgcykgewoKICAgIGlmIChzID09IG51bGwgfHwgcy5pc0JsYW5rKCkpIHJldHVybiBudWxsOwoKICAgIHRyeSB7IHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMudHJpbSgpKTsgfQoKICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeyByZXR1cm4gbnVsbDsgfQoKfQoKCgpwcml2YXRlIHN0YXRpYyBMb2NhbERhdGVUaW1lIHBhcnNlRGF0ZVRpbWVTYWZlbHkoU3RyaW5nIHMsIERhdGVUaW1lRm9ybWF0dGVyIHByaW1hcnkpIHsKCiAgICBpZiAocyA9PSBudWxsIHx8IHMuaXNCbGFuaygpKSByZXR1cm4gbnVsbDsKCiAgICBTdHJpbmcgdiA9IHMudHJpbSgpOwoKICAgIHRyeSB7IHJldHVybiBMb2NhbERhdGVUaW1lLnBhcnNlKHYsIHByaW1hcnkpOyB9CgogICAgY2F0Y2ggKERhdGVUaW1lUGFyc2VFeGNlcHRpb24gZTEpIHsKCiAgICAgICAgdHJ5IHsgcmV0dXJuIExvY2FsRGF0ZVRpbWUucGFyc2UodiwgRk1UX0ZBTExCQUNLKTsgfQoKICAgICAgICBjYXRjaCAoRGF0ZVRpbWVQYXJzZUV4Y2VwdGlvbiBlMikgeyByZXR1cm4gbnVsbDsgfQoKICAgIH0KCn0K
返回列表 上一筆 下一筆