import org.apache.axis.message.MessageElement;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
/** 建議:這個 formatter 放成 static 常數 */
private static final DateTimeFormatter FMT_PRIMARY = 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) 呼叫 web service,取得 MessageElement[]
WsGetTreeSubdirResponseWsGetTreeSubdirResult result = service.wsGetTreeSubdir(userType);
MessageElement[] anyArray = result.get_any();
if (anyArray == null || anyArray.length == 0) {
return Collections.emptyList();
}
// 2) 直接把第一個 MessageElement 當 root Element 使用(不經過 parse)
Element root = anyArray[0];
NodeList list = root.getElementsByTagName("TreeSubdir");
// 3) 逐筆解析成 flat beans
List<TreeNodeBean> flat = 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 bean = new TreeNodeBean();
bean.setIftSid(iftSid);
bean.setIftPrev(iftPrev);
bean.setFtName(sftName);
bean.setFtPathRaw(sftPath);
bean.setFtPathParts(splitPathSafe(sftPath));
bean.setKBCount(parseIntOrNull(iKBCount));
bean.setInitTime(parseDateTimeSafely(dInit));
bean.setModiTime(parseDateTimeSafely(dModi));
flat.add(bean);
}
// 4) 用 iftPrev 組樹,回傳 roots(你要 flat 就回傳 flat)
return TreeUtils.buildTree(flat);
}
/* ----------------- 小工具函式 ----------------- */
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) {
if (s == null || s.isBlank()) return null;
String v = s.trim();
try { return LocalDateTime.parse(v, FMT_PRIMARY); }
catch (DateTimeParseException e1) {
try { return LocalDateTime.parse(v, FMT_FALLBACK); }
catch (DateTimeParseException e2) { return null; }
}
}
aW1wb3J0IG9yZy5hcGFjaGUuYXhpcy5tZXNzYWdlLk1lc3NhZ2VFbGVtZW50OwoKaW1wb3J0IG9yZy53M2MuZG9tLkVsZW1lbnQ7CgppbXBvcnQgb3JnLnczYy5kb20uTm9kZUxpc3Q7CgppbXBvcnQgb3JnLnhtbC5zYXguU0FYRXhjZXB0aW9uOwoKCgppbXBvcnQgamF2YS50aW1lLkxvY2FsRGF0ZVRpbWU7CgppbXBvcnQgamF2YS50aW1lLmZvcm1hdC5EYXRlVGltZUZvcm1hdHRlcjsKCmltcG9ydCBqYXZhLnRpbWUuZm9ybWF0LkRhdGVUaW1lUGFyc2VFeGNlcHRpb247CgppbXBvcnQgamF2YS51dGlsLio7CgoKCi8qKiDlu7rorbDvvJrpgJnlgIsgZm9ybWF0dGVyIOaUvuaIkCBzdGF0aWMg5bi45pW4ICovCgpwcml2YXRlIHN0YXRpYyBmaW5hbCBEYXRlVGltZUZvcm1hdHRlciBGTVRfUFJJTUFSWSAgPSBEYXRlVGltZUZvcm1hdHRlci5vZlBhdHRlcm4oInl5eXkvTU0vZGQgSEg6bW06c3MiKTsKCnByaXZhdGUgc3RhdGljIGZpbmFsIERhdGVUaW1lRm9ybWF0dGVyIEZNVF9GQUxMQkFDSyA9IERhdGVUaW1lRm9ybWF0dGVyLm9mUGF0dGVybigieXl5eS1NTS1kZCBISDptbTpzcyIpOwoKCgpwdWJsaWMgTGlzdDxUcmVlTm9kZUJlYW4+IHRyYW5zZm9ybVRyZWUoU3RyaW5nIHVzZXJUeXBlKSB0aHJvd3MgRXhjZXB0aW9uIHsKCiAgICAvLyAxKSDlkbzlj6sgd2ViIHNlcnZpY2XvvIzlj5blvpcgTWVzc2FnZUVsZW1lbnRbXQoKICAgIFdzR2V0VHJlZVN1YmRpclJlc3BvbnNlV3NHZXRUcmVlU3ViZGlyUmVzdWx0IHJlc3VsdCA9IHNlcnZpY2Uud3NHZXRUcmVlU3ViZGlyKHVzZXJUeXBlKTsKCiAgICBNZXNzYWdlRWxlbWVudFtdIGFueUFycmF5ID0gcmVzdWx0LmdldF9hbnkoKTsKCiAgICBpZiAoYW55QXJyYXkgPT0gbnVsbCB8fCBhbnlBcnJheS5sZW5ndGggPT0gMCkgewoKICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CgogICAgfQoKCgogICAgLy8gMikg55u05o6l5oqK56ys5LiA5YCLIE1lc3NhZ2VFbGVtZW50IOeVtiByb290IEVsZW1lbnQg5L2/55So77yI5LiN57aT6YGOIHBhcnNl77yJCgogICAgRWxlbWVudCByb290ID0gYW55QXJyYXlbMF07CgogICAgTm9kZUxpc3QgbGlzdCA9IHJvb3QuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRyZWVTdWJkaXIiKTsKCgoKICAgIC8vIDMpIOmAkOethuino+aekOaIkCBmbGF0IGJlYW5zCgogICAgTGlzdDxUcmVlTm9kZUJlYW4+IGZsYXQgPSBuZXcgQXJyYXlMaXN0PD4obGlzdC5nZXRMZW5ndGgoKSk7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0LmdldExlbmd0aCgpOyBpKyspIHsKCiAgICAgICAgRWxlbWVudCBlID0gKEVsZW1lbnQpIGxpc3QuaXRlbShpKTsKCgoKICAgICAgICBTdHJpbmcgc2Z0UGF0aCAgPSBnZXRDaGlsZFRleHQoZSwgInNmdF9wYXRoIik7CgogICAgICAgIFN0cmluZyBpZnRTaWQgICA9IGdldENoaWxkVGV4dChlLCAiaWZ0X3NpZCIpOwoKICAgICAgICBTdHJpbmcgc2Z0TmFtZSAgPSBnZXRDaGlsZFRleHQoZSwgInNmdF9uYW1lIik7CgogICAgICAgIFN0cmluZyBpS0JDb3VudCA9IGdldENoaWxkVGV4dChlLCAiaUtCQ291bnQiKTsKCiAgICAgICAgU3RyaW5nIGRJbml0ICAgID0gZ2V0Q2hpbGRUZXh0KGUsICJkaW5pdF90aW1lIik7CgogICAgICAgIFN0cmluZyBkTW9kaSAgICA9IGdldENoaWxkVGV4dChlLCAiZG1vZGlfdGltZSIpOwoKICAgICAgICBTdHJpbmcgaWZ0UHJldiAgPSBnZXRDaGlsZFRleHQoZSwgImlmdF9wcmV2Iik7CgoKCiAgICAgICAgVHJlZU5vZGVCZWFuIGJlYW4gPSBuZXcgVHJlZU5vZGVCZWFuKCk7CgogICAgICAgIGJlYW4uc2V0SWZ0U2lkKGlmdFNpZCk7CgogICAgICAgIGJlYW4uc2V0SWZ0UHJldihpZnRQcmV2KTsKCiAgICAgICAgYmVhbi5zZXRGdE5hbWUoc2Z0TmFtZSk7CgogICAgICAgIGJlYW4uc2V0RnRQYXRoUmF3KHNmdFBhdGgpOwoKICAgICAgICBiZWFuLnNldEZ0UGF0aFBhcnRzKHNwbGl0UGF0aFNhZmUoc2Z0UGF0aCkpOwoKICAgICAgICBiZWFuLnNldEtCQ291bnQocGFyc2VJbnRPck51bGwoaUtCQ291bnQpKTsKCiAgICAgICAgYmVhbi5zZXRJbml0VGltZShwYXJzZURhdGVUaW1lU2FmZWx5KGRJbml0KSk7CgogICAgICAgIGJlYW4uc2V0TW9kaVRpbWUocGFyc2VEYXRlVGltZVNhZmVseShkTW9kaSkpOwoKCgogICAgICAgIGZsYXQuYWRkKGJlYW4pOwoKICAgIH0KCgoKICAgIC8vIDQpIOeUqCBpZnRQcmV2IOe1hOaoue+8jOWbnuWCsyByb290c++8iOS9oOimgSBmbGF0IOWwseWbnuWCsyBmbGF077yJCgogICAgcmV0dXJuIFRyZWVVdGlscy5idWlsZFRyZWUoZmxhdCk7Cgp9CgoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tIOWwj+W3peWFt+WHveW8jyAtLS0tLS0tLS0tLS0tLS0tLSAqLwoKCgpwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0Q2hpbGRUZXh0KEVsZW1lbnQgcGFyZW50LCBTdHJpbmcgdGFnKSB7CgogICAgTm9kZUxpc3QgbmwgPSBwYXJlbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnKTsKCiAgICBpZiAobmwgPT0gbnVsbCB8fCBubC5nZXRMZW5ndGgoKSA9PSAwKSByZXR1cm4gIiI7CgogICAgU3RyaW5nIHMgPSBubC5pdGVtKDApLmdldFRleHRDb250ZW50KCk7CgogICAgcmV0dXJuIHMgPT0gbnVsbCA/ICIiIDogcy50cmltKCk7Cgp9CgoKCnByaXZhdGUgc3RhdGljIExpc3Q8U3RyaW5nPiBzcGxpdFBhdGhTYWZlKFN0cmluZyByYXcpIHsKCiAgICBpZiAocmF3ID09IG51bGwpIHJldHVybiBMaXN0Lm9mKCk7CgogICAgU3RyaW5nIHMgPSByYXcudHJpbSgpOwoKICAgIGlmIChzLnN0YXJ0c1dpdGgoIlxcIikpIHMgPSBzLnN1YnN0cmluZygxKTsKCiAgICBpZiAocy5lbmRzV2l0aCgiXFwiKSkgICBzID0gcy5zdWJzdHJpbmcoMCwgcy5sZW5ndGgoKSAtIDEpOwoKICAgIGlmIChzLmlzRW1wdHkoKSkgcmV0dXJuIExpc3Qub2YoKTsKCiAgICBTdHJpbmdbXSBwYXJ0cyA9IHMuc3BsaXQoIlxcXFwiKTsKCiAgICBMaXN0PFN0cmluZz4gb3V0ID0gbmV3IEFycmF5TGlzdDw+KHBhcnRzLmxlbmd0aCk7CgogICAgZm9yIChTdHJpbmcgcCA6IHBhcnRzKSBpZiAocCAhPSBudWxsICYmICFwLmlzQmxhbmsoKSkgb3V0LmFkZChwLnRyaW0oKSk7CgogICAgcmV0dXJuIG91dDsKCn0KCgoKcHJpdmF0ZSBzdGF0aWMgSW50ZWdlciBwYXJzZUludE9yTnVsbChTdHJpbmcgcykgewoKICAgIGlmIChzID09IG51bGwgfHwgcy5pc0JsYW5rKCkpIHJldHVybiBudWxsOwoKICAgIHRyeSB7IHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHMudHJpbSgpKTsgfQoKICAgIGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgeyByZXR1cm4gbnVsbDsgfQoKfQoKCgpwcml2YXRlIHN0YXRpYyBMb2NhbERhdGVUaW1lIHBhcnNlRGF0ZVRpbWVTYWZlbHkoU3RyaW5nIHMpIHsKCiAgICBpZiAocyA9PSBudWxsIHx8IHMuaXNCbGFuaygpKSByZXR1cm4gbnVsbDsKCiAgICBTdHJpbmcgdiA9IHMudHJpbSgpOwoKICAgIHRyeSB7IHJldHVybiBMb2NhbERhdGVUaW1lLnBhcnNlKHYsIEZNVF9QUklNQVJZKTsgfQoKICAgIGNhdGNoIChEYXRlVGltZVBhcnNlRXhjZXB0aW9uIGUxKSB7CgogICAgICAgIHRyeSB7IHJldHVybiBMb2NhbERhdGVUaW1lLnBhcnNlKHYsIEZNVF9GQUxMQkFDSyk7IH0KCiAgICAgICAgY2F0Y2ggKERhdGVUaW1lUGFyc2VFeGNlcHRpb24gZTIpIHsgcmV0dXJuIG51bGw7IH0KCiAgICB9Cgp9Cg==