package com.smtscript.lib.yml; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.smtscript.lib.JSStaticYML; import com.smtscript.utils.SMTStatic; public class JSYMLModify { private static class PropItem { public String _value; public String _keyPath; public int _lineno; public int _space; // 空格个数 public int _start; // 值开始位置 public PropItem(int lineno, int space, int start, String keyPath, String value) { _lineno = lineno; _value = value; _space = space; _start = start; _keyPath = keyPath; } @Override public String toString() { return String.format("%s - %d - %s", _keyPath, _lineno, _value); } } private List _lines = new ArrayList(); private Map _mapKey2PropItem = new LinkedHashMap(); private static Pattern _patLine = Pattern.compile("^(\\s*)([^#\\s:]+)\\s*:\\s*(.*)"); public JSYMLModify(JSStaticYML parent, File file) throws Exception { loadPropertiesStream(new FileInputStream(file)); } public JSYMLModify(JSStaticYML parent, String propStr) throws Exception { loadPropertiesStream(new ByteArrayInputStream(propStr.getBytes("UTF-8"))); } private void loadPropertiesStream(InputStream is) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); try { String line; List stack = new ArrayList(); while((line = br.readLine()) != null) { _lines.add(line); Matcher m = _patLine.matcher(line); if(m.find()) { String space = m.group(1); int curPerfixLen = SMTStatic.isNullOrEmpty(space) ? 0 : space.length(); // 删除比当前层级高或相等的信息 while(stack.size() > 0) { int lastPerfixLen = stack.get(stack.size() - 1)._space; if(curPerfixLen > lastPerfixLen) break; stack.remove(stack.size() - 1); } // 获取当前的keyPath String keyPath = ""; if(stack.size() > 0) keyPath = stack.get(stack.size() - 1)._keyPath + "." + m.group(2); else keyPath = m.group(2); // 创建当前项,并插入列表 PropItem propItem = new PropItem(_lines.size() - 1,curPerfixLen, m.start(3), keyPath, m.group(3)); stack.add(propItem); _mapKey2PropItem.put(keyPath, propItem); } } } finally { br.close(); } } public boolean hasKey(String key) { return _mapKey2PropItem.containsKey(key); } public String getValue(String key, String defVal) throws Exception { PropItem propItem = _mapKey2PropItem.get(key); if(propItem == null) return defVal; return propItem._value; } public String getValue(String key) throws Exception { PropItem propItem = _mapKey2PropItem.get(key); if(propItem == null) throw new Exception("can't find key : " + key); return propItem._value; } public void setValue(String key, String value) throws Exception { PropItem propItem = _mapKey2PropItem.get(key); if(propItem == null) throw new Exception("can't find key : " + key); propItem._value = value; String leftStr = _lines.get(propItem._lineno).substring(0, propItem._start); _lines.set(propItem._lineno, leftStr + value); } public String getFullText() { StringBuilder sb = new StringBuilder(); for(String line : _lines) { sb.append(line + "\n"); } return sb.toString(); } public void save(String fileName) throws Exception { SMTStatic.saveTextFile(new File(fileName), getFullText(), "UTF-8"); } }